这里scanf的缓存区为什么会多一个1?

这里scanf的缓存区为什么会多一个1?

img


完整代码:
test.h:

#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
typedef struct guan
{
    char* id;
    char* name;
    int* sl;
    double* price;
}guan;
void lr(guan guan1[], int* num); //录入设备 
void ck(guan guan[], int* num);
void guanliyuan();

test.cpp:

#include<stdio.h>
#define _CRT_SECURE_NO_WARNINGS

#include"test.h"
/*struct guan
{
 char *id;
 char *name;
 int state;
 int sl;
 double price;
}sheb;*/
void jinru()
{
    printf("         欢迎使用设备借还系统        \n");
    printf("(1)管理员系统\n");
    printf("(2)用户登录系统\n");
    printf("(3)用户注册系统\n");
    printf("(4)退出\n");
    printf("请输入:");
}

int main()
{
    int a;
    struct guan guan[1000];
    jinru();
    scanf("%d", &a);
    switch (a)
    {
    case 1:
        guanliyuan();
        break;
    case 2:
        printf("用户登录系统\n");
        break;
    case 3:
        printf("用户注册系统\n");
        break;
    case 4:
        printf("退出\n");
        break;
    default:
        printf("error\n");
        break;
    }
}

test2.cpp:

#include"test.h"
void lr(guan guan1[], int* num)
{
    while (1)
    {
        printf("请输入设备编号:\n");
        scanf("%c\n", &guan1[*num].id);
        printf("请输入设备名称:\n");
        scanf("%c\n", &guan1[*num].name);
        printf("请输入设备数量:\n");
        scanf("%d\n", &guan1[*num].sl);
        printf("请输入设备价格:\n");
        scanf("%lf\n", &guan1[*num].price);
        (*num)++;
        char j;
        printf("是否继续录入(y/n):\n");
        //getchar();
        scanf(" %c", &j);
        if (j == 'y')
        {
            continue;
        }
        else
        {
            break;
        }
    }

}

void ck(guan guan[], int* num)
{
    while (1)
    {
        printf("设备名称是:%c\n", guan[(*num)].name);
        printf("设备数量是:%d\n", guan[*num].sl);
        printf("设备价格是:%lf\n", guan[*num].price);
        char c;
        printf("是否继续查看设备(y/n):\n");
        scanf(" %c\n", &c);
        if (c == 'y')
        {
            continue;
        }
        else
        {
            break;
        }
    }
}

void guanliyuan()
{
    int b;
    guan guan1[1000];
    printf("         管理员系统        \n");
    printf("(1)录入设备\n");
    printf("(2)查看已存设备\n");
    printf("(3)修改已有设备信息\n");
    printf("(4)登记破损设备\n");
    printf("(5)注销现存设备\n");
    printf("(6)返回\n");
    printf("请输入:\n");
    scanf("%d", &b);
    int num = 0;
    switch (b)
    {
    case 1:
        lr(guan1, &num);
        break;
    case 2:
        ck(guan1, &num);
        break;
    case 3:
    case 4:
    case 5:
    case 6:
    default:
        printf("error\n");
        break;
    }
}

这不是多个1
你得会看调试器
这里49是'1'的ascii码,'1'是你输入的字符
49'1'这是同一个值,不是2个值

  • 你可以看下这个问题的回答https://ask.csdn.net/questions/7806967
  • 我还给你找了一篇非常好的博客,你可以看看是否有帮助,链接:C语言scanf()与缓冲区
  • 除此之外, 这篇博客: <C语言>| 关于scanf读取缓存区的理解中的 功能:执行格式化输入 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 并且注意:scanf()函数返回成功赋值的数据项数,出错时则返回EOF。

    当进一步深挖之后(暂时不需要知道原理,只需要知道结果即可),
    可以得到这样一个认识:
    键盘输入的东西并没有直接给scanf读取 而是在缓冲区进行暂时存放
    比如这样一段代码:
    #include <stdio.h>
    int main()
    {
    int a, b, c, d, e;
    scanf("%d %d %d %d", &a, &b, &c, &d);
    printf("%d %d %d %d\n", a, b, c, d);
    scanf("%d", &e);
    printf("%d\n", e);
    return 0;
    }

    预期:1 2 3 4

    ​ 1 2 3 4

    ​ 5

    ​ 5

    但是如果你这样输入: 1 2 3 4 5

    会输出 1 2 3 4

    ​ 5

    这是因为scanf以回车键为信号,去缓冲区进行读取数据,只要数据的格式符合标准,那么就可以正确读取,否则就要等待继续输入/读取失败

  • 您还可以看一下 传智老师的2016年c语言教程第3天课程中的 07 使用scanf函数一次接收输入多个数据小节, 巩固相关知识点

因为结构体定义里,所有成员字段都是指针类型,


typedef struct guan
{
    char* id;
    char* name;
    int* sl;
    double* price;
}guan;

然后lr() 函数里,输入语句读入字符型?

 while (1)
    {
        printf("请输入设备编号:\n");
        scanf("%c\n", &guan1[*num].id);
        printf("请输入设备名称:\n");
        scanf("%c\n", &guan1[*num].name);
        printf("请输入设备数量:\n");
        scanf("%d\n", &guan1[*num].sl);
        printf("请输入设备价格:\n");
        scanf("%lf\n", &guan1[*num].price);
        (*num)++;


几个文件整体修改如下,改动处见注释,供参考:

//test.h:
#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
typedef struct Guan  //修改
{
    char   id[13];   //char* id;
    char   name[16]; //char* name;
    int    sl;       //int* sl;
    double price;    // double* price;
}guan;
void lr(guan guan1[], int* num); //录入设备 
void ck(guan guan[], int* num);
void guanliyuan();



//test2.cpp:
#include"test.h"
void lr(guan guan1[], int* num)
{
    while (1)
    {
        printf("请输入设备编号:\n");
        scanf("%s", guan1[*num].id);  //scanf("%c\n", &guan1[*num].id);
        getchar();
        printf("请输入设备名称:\n");
        scanf("%s", guan1[*num].name);  //scanf("%c\n", &guan1[*num].name);
        getchar();
        printf("请输入设备数量:\n");
        scanf("%d", &guan1[*num].sl); //scanf("%d\n", &guan1[*num].sl);
        getchar();
        printf("请输入设备价格:\n");
        scanf("%lf", &guan1[*num].price); //scanf("%lf\n", &guan1[*num].price);
        getchar();
        (*num)++;
        char j;
        printf("是否继续录入(y/n):\n");
        //getchar();
        scanf(" %c", &j);
        if (j == 'y')
        {
            continue;
        }
        else
        {
            break;
        }
    }

}

void ck(guan guan[], int* num)
{
    while (1)
    {
        printf("设备名称是:%s\n", guan[(*num)].name); //printf("设备名称是:%c\n", guan[(*num)].name);
        printf("设备数量是:%d\n", guan[*num].sl);  
        printf("设备价格是:%lf\n", guan[*num].price);
        char c;
        printf("是否继续查看设备(y/n):\n");
        scanf(" %c", &c);  //scanf(" %c\n", &c);
        if (c == 'y')
        {
            continue;
        }
        else
        {
            break;
        }
    }
}

void guanliyuan()
{
    int b;
    guan guan1[1000];
    printf("         管理员系统        \n");
    printf("(1)录入设备\n");
    printf("(2)查看已存设备\n");
    printf("(3)修改已有设备信息\n");
    printf("(4)登记破损设备\n");
    printf("(5)注销现存设备\n");
    printf("(6)返回\n");
    printf("请输入:\n");
    scanf("%d", &b);
    int num = 0;
    switch (b)
    {
    case 1:
        lr(guan1, &num);
        break;
    case 2:
        ck(guan1, &num);
        break;
    case 3:
    case 4:
    case 5:
    case 6:
    default:
        printf("error\n");
        break;
    }
}