正在跳过fgets()的第一个实例

Exi*_*kle 1 c input fgets

所以我正在练习c,当我使用fgets()时,我得到了这个bug.代码的第一个实例被跳过并转到下一行.

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");
  }
Run Code Online (Sandbox Code Playgroud)

我在本节之前使用scanf(),所以我发现我必须刷新缓冲区.然而,这是行不通的.

输出通常是:

Student 0
First Name:Last Name:(Cursor)
Run Code Online (Sandbox Code Playgroud)

pax*_*blo 6

你必须小心混合不同的输入方法,如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;
}
Run Code Online (Sandbox Code Playgroud)

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

123[ 456
]
Run Code Online (Sandbox Code Playgroud)

在那里你可以看到,在fgets扫描的整数之后,从第一个非数字空间到最后一个换行符,它已经拾取了剩余的一行.

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

还有一些方法可以允许混合不同的输入方法,例如在scanf获得换行符之后读取字符,有效地丢弃行的其余部分(包括换行符).

但也许最简单的方法是使用定制的,经过验证的线条输入函数来获取线条,然后sscanf使用线条来获得您想要的线条,例如线条.

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