为什么我的第二个“scanf”被跳过了?

时间:2014-10-17 01:05:24

标签: c scanf

这是我的主要功能..

    printf("How many marking components in the course? ");
    scanf("%d", &numberOfComponents );
    for (int i=0; i<numberOfComponents; i++){

            char c[MAX_STR];
            printf("enter next component name: ");
            fgets(c, sizeof(c), stdin);
            scanf(c, " %c", &c);


            Component comp;

            initComp(&comp, c);
            class.comps[i] = comp;

            }

    printf("How many marking schemes? ");
    scanf(" %d", &numberOfSchemes);

我已经尝试了空白区域,但它仍然存在

2 个答案:

答案 0 :(得分:1)

您应该测试您的输入操作是否有效;当你不这样做时,事情会变得混乱。

此次致电scanf()

scanf(c, " %c", c);

应该(在他chux中的answer诊断)的写法不同,但我认为应该更像:

char filler;
if (scanf(" %c", &filler) != 1)
    …report problem…

原始版本使用刚读取的行作为格式字符串,几乎可以肯定与第二个输入匹配失败。如果您只使用scanf(" %c", c)这是最简单的编辑,那么您将使用下一个非空白字符覆盖输入行的第一个字符。

然后就是为什么要让用户在组件名称后输入额外数据的问题。他们必须输入一些东西。在下一个fgets()上,代码将在第一个字符之后读取到下一个换行符。所以,如果你输入:

component-1
component-2

第一个fgets()会读取component-1和换行符;修改后的scanf()会将c的{​​{1}}读成component-2,然后下一个c[0]会读取fgets()加上换行符{ {1}}在下一次迭代中。

您可以通过添加代码来查看更多内容,以便在阅读时阅读您所阅读的内容:

omponent-2

这是最基本的调试技术之一;回应你所读到的内容,以确保程序获得你认为的数据。

答案 1 :(得分:0)

fgets()scanf()混合经常会导致问题。

scanf("%d"...会在'\n' stdin中留下fgets()之后的任何空格,以获取scanf(c, " %c", &c);scanf(" %c", c);之后也是如此(可能是sscanf(c, " %c", c);scanf("%d", &numberOfComponents ); ... fgets(c, sizeof(c), stdin); )。

fgets()

建议仅使用sscanf()获取用户输入,并使用strtol()fgets(c, sizeof(c), stdin); sscanf(c, "%d", &numberOfComponents ); .... fgets(c, sizeof(c), stdin); // I do not think you need the following line of code. // Besides it is UB as it attempts to scan and save into the same buffer. // sscanf(c, "%c", &c ); 等来解析该输入。

fgets(), sscanf()

错误检查{{1}}的结果被忽略了,但仍然很好。