【问题标题】:Why isn't scanf accepting elements into this C structure?为什么 scanf 不接受元素进入这个 C 结构?
【发布时间】:2014-07-31 05:02:47
【问题描述】:

我是 C 新手,正在学习结构。我创建了一个简单的结构并尝试在结构变量中通过scanf() 输入输入值,但我只得到部分/垃圾输出。我在这里错过了什么吗?

这是我的原始代码-

#include<stdio.h>
void main()
{
    struct book
    {
        char name;
        float price;
        int pages;
    };

    struct book b1,b2,b3;
    int i;
    printf("\n Enter the names, prices and no. of pages of the 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("\n You have entered: \n");
    printf("%c %.2f %d", b1.name,b1.price, b1.pages);
    printf("%c %.2f %d", b2.name,b2.price, b2.pages);
    printf("%c %.2f %d", b3.name,b3.price, b3.pages);
}

这是一组输出-

Enter names, prices & no. of pages of 3 books
A 230.5 13
B 345.9 33

And this is what you entered
A 230.50 13

 0.00 3
B 345.89 33

如你所见:

  1. 一旦我输入第二个structure variable(b2) 的信息,printf() 就会停止工作并且不接受信息。关于第三个structure variable(b3)
  2. 当它突然停止通过scanf() 接受值时,我在第二行得到一些垃圾值-0.00 3

我想也许结构定义应该总是在main()之外,所以我什至修改它以在main()之外定义struct book并在main()中声明变量struct book b1,b2,b3;,但它没有任何效果。

我在这里做错了什么?

更新-

我知道在 SO here 上存在类似的答案,但这里的问题是 addressof(&amp;) 运算符不包含在 scanf()

【问题讨论】:

  • 您是先前输入的尾随换行符的受害者。您需要一种从输入缓冲区中删除(吃掉它)的方法。
  • 那么,我应该使用 fflush(stdin) 之类的东西吗?
  • @DarkKnight fflush(stdin) 没有在标准 C 中定义。即使它可以在您的机器上运行,使用它也会使您的程序不可移植。
  • 哦,我明白了。那我该如何摆脱尾随的换行符呢?
  • @DarkKnight void eat_newline(){int c; while((c = getchar()) != '\n' &amp;&amp; c != EOF) ;} 或更好的选择,请参阅 YuHao 回答

标签: c struct structure scanf


【解决方案1】:

输入第一行值后,按回车,换行符仍在输入缓冲区中,将在下一个scanf 中由"%c" 处理。

要解决此问题,请勿使用scanf。相反,使用fgets 获取每一行,然后使用sscanf 从每一行获取值。

【讨论】:

  • 你能举个例子吗?我以前从未将 fgets 与 sscanf 一起使用过,所以。
  • @DarkKnight sscanf 的用法与scanf 的用法相似,不同之处在于它适用于字符串。您只需要学习如何使用fgets 获取输入行,例如char line[100]; fgets(line, 100, stdin);
  • 谢谢,我知道fgets() 的格式和使用方法,但不确定sscanf() 是否与fgets() 一起使用
  • @DarkKnight 使用line作为第一个参数,其余与scanf相同:sscanf(line, "%c %f %d", &amp;b1.name,&amp;b1.price, &amp;b1.pages);
【解决方案2】:

大多数书名都超过一个字符,但%c 格式将书名限制为一个字符。您的结构也只存储一个字符,因此您需要更改定义以允许更长的标题。更有问题的是,大多数书名都超过一个单词,但%s 格式是%c 的“明显”替代方案,只能读取第一个空格,这意味着它只读取第一个单词。

您还应该在每次使用它时检查来自scanf() 的返回值。如果不是 3,则出现问题。你有问题的原因是输入的第一行以换行符结尾,%d格式不读取,所以%c读取,然后字母上的数字转换失败。您可以通过在%c 之前使用带有空格的" %c %.2f %d" 来跳过可选的前导空格(这将跳过换行符;它被视为空格)来解决此问题。

对此没有简单的解决方法。您需要知道如何将标题的结尾与价格和页面区分开来。我可能会使用fgets() 来读取整行输入。然后我会向后扫描以查找页数和价格;该行的剩余部分可能是书名。

【讨论】:

    【解决方案3】:
    #include<stdio.h>
    #include<string.h>
    
    void main()
    {
            struct book
            {
                    char name[99];
                    float price;
                    int pages;
            };
    
            struct book b1,b2,b3;
            int i,ch;
            printf("\n Enter the names \n");
            gets(b1.name);
    
            printf("\n enter the price\n");
            scanf("%f",&b1.price);
            printf("\n enter the pages\n");
            scanf("%d",&b1.pages);
            while ((ch = fgetc(stdin)) != EOF && ch != '\n')
            {
            }
            printf("\n Enter the names \n");
    
            gets(b2.name);
            printf("\n enter the price\n");
            scanf("%f",&b2.price);
            printf("\n enter the pages\n");
            scanf("%d",&b2.pages);
            while ((ch = fgetc(stdin)) != EOF && ch != '\n')
            {
            }
            printf("\n Enter the names \n");
    
            gets(b3.name);
            printf("\n enter the price\n");
            scanf("%f",&b3.price);
            printf("\n enter the pages\n");
            scanf("%d",&b3.pages);
    
            printf("\n You have entered: \n");
            printf("%s %.2f %d\n", b1.name,b1.price, b1.pages);
            printf("%s %.2f %d\n", b2.name,b2.price, b2.pages);
            printf("%s %.2f %d\n", b3.name,b3.price, b3.pages);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-06
      • 2015-12-11
      • 2021-12-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多