在 C 中 scanf() 之后使用 fgets()/gets()/scanf() 的问题
scanf()是 C 语言中的一个库函数。它从标准输入读取标准输入。 fgets()是 C 语言中的一个库函数。它从指定的流中读取一行并将其存储到字符串变量指向的字符串中。它仅在以下任一情况下终止:
- 到达文件结尾
- 读取 n-1 个字符
- 读取字符
1)考虑下面一个简单的 C 程序。该程序使用 scanf() 读取一个整数,然后使用 fgets() 读取一个字符串,
输入
10
test
C
// C program to demonstrate the problem when
// fgets()/gets() is used after scanf()
#include
int main()
{
int x;
char str[100];
scanf("%d", &x);
fgets(str, 100, stdin);
printf("x = %d, str = %s", x, str);
return 0;
}
C
// C program to demonstrate the problem when
// scanf() is used in a loop
#include
int main()
{
char c;
printf("Press q to quit\n");
do {
printf("Enter a character\n");
scanf("%c", &c);
printf("%c\n", c);
} while (c != 'q');
return 0;
}
C
// C program to demonstrate the problem when
// fgets()/gets() is used after scanf()
#include
int main()
{
int x;
char str[100];
scanf("%d\n", &x);
fgets(str, 100, stdin);
printf("x = %d, str = %s", x, str);
return 0;
}
C
// C program to demonstrate the problem when
// scanf() is used in a loop
#include
// Driver Code
int main()
{
char c;
printf("Press q to quit\n");
do {
printf("Enter a character\n");
scanf("%c\n", &c);
printf("%c\n", c);
} while (c != 'q');
return 0;
}
输出
x = 10, str =
解释:上述代码的问题是 scanf() 读取一个整数并在缓冲区中留下一个字符。所以 fgets() 只读取换行符,字符串“test”被程序忽略。
2)在循环中使用scanf()时也会出现类似的问题。
输入:
a
b
q
C
// C program to demonstrate the problem when
// scanf() is used in a loop
#include
int main()
{
char c;
printf("Press q to quit\n");
do {
printf("Enter a character\n");
scanf("%c", &c);
printf("%c\n", c);
} while (c != 'q');
return 0;
}
输出
Press q to quit
Enter a character
a
Enter a character
Enter a character
b
Enter a character
Enter a character
q
解释:我们可以注意到上面的程序打印了一个额外的“输入一个字符”,然后是一个额外的换行符。发生这种情况是因为每个 scanf() 都会在缓冲区中留下一个字符,由下一个 scanf 读取。
如何解决上述问题?
- 我们可以通过使用额外的\n使scanf()读取新行,即scanf(“%d\n”, &x) 。事实上scanf("%d ", &x)也可以(注意多余的空格)。
- 我们可以在scanf( ) 之后添加一个 getchar( ) 来读取额外的换行符。
以上几点的更正程序将是,
1) scanf() 后面有 fgets() 时:
输入:
10
test
C
// C program to demonstrate the problem when
// fgets()/gets() is used after scanf()
#include
int main()
{
int x;
char str[100];
scanf("%d\n", &x);
fgets(str, 100, stdin);
printf("x = %d, str = %s", x, str);
return 0;
}
输出
x = 10, str = test
2) 当 scanf() 在循环中使用时:
输入:
a
b
q
C
// C program to demonstrate the problem when
// scanf() is used in a loop
#include
// Driver Code
int main()
{
char c;
printf("Press q to quit\n");
do {
printf("Enter a character\n");
scanf("%c\n", &c);
printf("%c\n", c);
} while (c != 'q');
return 0;
}
输出:按q退出
Enter a character
a
Enter a character
b
Enter a character
q
必读:当在 nextXXX() 之后使用 nextLine() 时, Java中的 Scanner 会出现问题