三个scanf导致两个和获取垃圾值

三个scanf导致两个和获取垃圾值,c,char,scanf,C,Char,Scanf,下面是基本结构的代码,但输出不符合预期。有三个scanf函数,但只有两个正在执行。中间一个包含垃圾值 #include <stdio.h> int main() { struct book { char name; float price; int pages; }; struct book b1,b2,b3; printf("Enter names , prices & no of

下面是基本结构的代码,但输出不符合预期。有三个scanf函数,但只有两个正在执行。中间一个包含垃圾值

#include <stdio.h>

int main()
{
    struct book
    {
        char name;
        float price;
        int pages;
    };

    struct book b1,b2,b3;

    printf("Enter names , prices & no of pages of 3 books\n");
    scanf("%c%f%d",&b1.name,&b1.price,&b1.pages);
    scanf("%c%f%d",&b2.name,&b2.price,&b2.pages);
    scanf("%c%f%d",&b3.name,&b3.price,&b3.pages);

    printf("And this is what you entered\n");
    printf("%c%f%d",b1.name,b1.price,b1.pages);
    printf("%c%f%d",b2.name,b2.price,b2.pages);
    printf("%c%f%d",b3.name,b3.price,b3.pages);

    return 0;
}
#包括
int main()
{
结构体的构造
{
字符名;
浮动价格;
整版;
};
结构书b1、b2、b3;
printf(“输入名称、价格和3本书的页数\n”);
scanf(“%c%f%d”、&b1.name、&b1.price、&b1.pages);
scanf(“%c%f%d”、&b2.name、&b2.price、&b2.pages);
scanf(“%c%f%d”、&b3.name、&b3.price、&b3.pages);
printf(“这是您输入的\n”);
printf(“%c%f%d”,b1.名称,b1.价格,b1.页);
printf(“%c%f%d”,b2.name,b2.price,b2.pages);
printf(“%c%f%d”,b3.名称,b3.价格,b3.页);
返回0;
}

scanf通常从标准输入流读取字符,其中包括换行符和空格。因此,在使用scanf(“%c”)之前,请尝试刷新stdin流中剩余的所有不需要的输入

还请记住:不要让%c在格式字符串

中间的某个地方落下。 希望这能有所帮助。不幸的是,您应该在“您的”程序中的所有scanf之前使用它

您也可以在scanf中使用%c之前的空格来读取空格

scanf(" %c"....);
简单地改变

scanf("%c%f%d", &bx.name, &bx.price, &bx.pages);

按Enter键后,“\n”留在
stdin
中,稍后将由“%c”使用。读取字符('\n')后,
scanf()
需要一个浮点数,如字符串格式中的“%f”所示。但是,它没有得到所需的浮点数,而是遇到了一个字符,返回结果很糟糕。因此,
&bx.price
&bx.pages
不会更新,因此它们保持未初始化状态,从而为您提供垃圾值

scanf()
中有一个前导空格,在开始读取之前,将丢弃所有空白字符(如果有)。由于
\n
已被丢弃,下面的读取过程(大概)将成功

另外,还有一个提示:始终检查
scanf()的返回值,因为您永远不知道用户将输入哪些内容

示例代码:

#include <stdio.h>

struct book
{
    char name;
    float price;
    int pages;
};

int main()
{
    struct book b1, b2, ..., bx;

    printf("Enter names, prices & no of pages of x books:\n");
    while (scanf(" %c%f%d", &bx.name, &bx.price, &bx.pages) != 3)
    { 
        fputs("Error reading bx. Please try again:\n", stderr);
        scanf("%*[^\n] ");
    }
    ......

    printf("And this is what you have entered:\n");
    printf("%c %f %d", bx.name, bx.price, bx.pages);
    ......

    return 0;
}

scanf(“%c%f%d”
-->
scanf(“%c%f%d”
由于一些缓冲规则,在数字或浮点之前提供一些空格,例如
scanf(“%c%d%f”,bla,blaa,blaaa);
您需要检查scanf的返回值:
如果(scanf(“%c%f%d”,&b1.name,&b1.price,&b1.pages)!=3){fprintf(stderr,“读取b1输入错误”。\n”);退出(EXIT_FAILURE);}
跳过previos换行。@SCaffrey输入未完成。它将继续等待非空的输入。这不是
fflush(stdin);
未定义的行为吗?@孙庆尧是
fflush(stdin)
是UB.C11规范:“如果流指向输出流或更新流…fflush函数会导致该流的任何未写入数据被传递…否则,行为未定义。”。
stdin
不是输出流或更新流。在某些系统上,
fflush(stdin)
它清空流,并且其他机器上的相同代码具有不同的结果。健壮代码不使用
fflush(stdin)
scanf(" %c%f%d", &b1.name, &b1.price, &b1.pages);
#include <stdio.h>

struct book
{
    char name;
    float price;
    int pages;
};

int main()
{
    struct book b1, b2, ..., bx;

    printf("Enter names, prices & no of pages of x books:\n");
    while (scanf(" %c%f%d", &bx.name, &bx.price, &bx.pages) != 3)
    { 
        fputs("Error reading bx. Please try again:\n", stderr);
        scanf("%*[^\n] ");
    }
    ......

    printf("And this is what you have entered:\n");
    printf("%c %f %d", bx.name, bx.price, bx.pages);
    ......

    return 0;
}
Enter names, prices & no of pages of x books:
asd wedewc efcew
Error reading bx. Please try again:
a 12.34 42
And this is what you have entered:
a 12.340000 42