【问题标题】:fgets()'s first instance is being skippedfgets() 的第一个实例被跳过
【发布时间】:2016-01-12 21:41:34
【问题描述】:

所以我正在练习 c 并且在使用 fgets() 时遇到了这个错误。代码的第一个实例被跳过并转到下一行。

代码

for(g = 0;g<numStudents;g++)
  {
    array->firstName = malloc(sizeof(char)*BUFSIZE);
    array->lastName = malloc(sizeof(char)*BUFSIZE);

    printf("Student %d\n", g+1);
    printf("First Name:");
    fgets(array->firstName, BUFSIZE, stdin);
    printf("Last Name:");
    fgets(array->lastName, BUFSIZE, stdin);
    printf("\n\n");
  }

我在本节之前使用了 scanf(),所以我发现我必须刷新缓冲区。但是,这不起作用。

输出通常是:

Student 0
First Name:Last Name:(Cursor)

【问题讨论】:

  • sizeof(char) == 1 是必填项,您能发表您的意见吗?也没有必要使用malloc() 固定大小。
  • 至少,Does scanf() take '\n' as input left over from previous scanf() 的答案适用于您的情况。 scanf() 可能会在输入流中留下一个换行符,fgets() 将其读取为第一个输入“行”。我会将其作为副本关闭,但我宁愿在使用 Mjolnir 之前达成一些共识。
  • scanf 之后如何刷新缓冲区?
  • 在循环前使用while((int c=getchar())!='\n' &amp;&amp; c!=EOF);

标签: c input fgets


【解决方案1】:

您必须小心混合不同的输入法,例如scanffgets。如果您scanf("%d") 并输入一个整数后跟一个换行符,则指针将留在换行符处(第一个字符对于构造整数无效),所以 那就是下面的fgets如您所见,将接起。

例如,考虑以下小程序:

#include <stdio.h>
int main (void) {
    int val;
    char buffer[100];
    scanf ("%d", &val);
    fgets (buffer, sizeof(buffer), stdin);
    printf ("%d[%s]\n", val, buffer);
    return 0;
}

如果你编译/运行它,然后输入123 456,你将看到的输出是:

123[ 456
]

在那里你可以看到fgets 已经拾取了扫描整数之后的其余行,从第一个非数字空格到末尾的换行符。

如果您单独使用scanf,通常没问题,因为大多数(但不是全部)格式说明符会在读取其项目之前跳过前导空格。

还有一些方法可以混合使用不同的输入法,例如读取scanf 之后的字符直到换行,从而有效地丢弃该行的其余部分(包括换行符)。

但也许最简单的方法是使用定制的、经过验证的 line-input 函数来获取行,然后通过 sscanf 获取所需的行,例如 this one .

这样,所有输入都是基于行的,您仍然可以使用scanf 从行中提取数据。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-15
    • 1970-01-01
    相关资源
    最近更新 更多