📅  最后修改于: 2023-12-03 15:37:10.781000             🧑  作者: Mango
在 C 语言中,我们通常使用输入函数来从用户那里接受输入。其中,fgets()
、gets()
和 scanf()
是最常用的函数之一。然而,在一些特殊情况下,当我们在一个程序中混合使用这些函数时,会出现一些问题。本文将讨论其中一个常见的问题:当 fgets()
或 gets()
函数在 scanf()
函数之前被调用时,scanf()
函数可能不会如预期工作。
考虑下面这段代码:
#include <stdio.h>
int main() {
char str[100], name[30];
int age;
printf("Enter your name: ");
fgets(name, 30, stdin);
// 或者:
// gets(name);
printf("Enter your age: ");
scanf("%d", &age);
printf("Enter a string: ");
fgets(str, 100, stdin);
// 或者:
// gets(str);
printf("Name: %s\n", name);
printf("Age: %d\n", age);
printf("String: %s\n", str);
return 0;
}
程序提示用户输入姓名、年龄和字符串,然后将这些值输出到屏幕上。这个程序似乎没有任何问题,但当我们运行程序并尝试输入值时,会发现第二次输入会被跳过。
Enter your name: Alice
Enter your age: 20
Enter a string:
Name: Alice
Age: 20
String:
这个问题的原因在于当调用 scanf()
函数后,键盘缓冲区中会有一个换行字符(\n
)被留在那里。例如,在上面的程序中,当用户输入年龄时,按下回车键会将 \n
字符留在键盘缓冲区中。
然而,在调用 fgets()
或 gets()
函数时,这个换行符会被读取进来,因此 fgets()
或 gets()
函数会立即返回而不等待用户输入任何值。
要解决这个问题,我们可以使用以下两种方法之一:
在调用 fgets()
或 gets()
函数之后调用 getchar()
函数,将键盘缓冲区中的换行符读取并丢弃。
printf("Enter your name: ");
fgets(name, 30, stdin);
getchar(); // 读取缓冲区中的换行符
printf("Enter your age: ");
scanf("%d", &age);
getchar(); // 读取缓冲区中的换行符
printf("Enter a string: ");
fgets(str, 100, stdin);
getchar(); // 读取缓冲区中的换行符
使用 scanf()
函数代替 fgets()
或 gets()
函数获取字符串输入。
printf("Enter your name: ");
scanf("%29s", name); // 限制最大读入字符数为 29,以避免缓冲区溢出
printf("Enter your age: ");
scanf("%d", &age);
printf("Enter a string: ");
scanf("%99s", str); // 限制最大读入字符数为 99,以避免缓冲区溢出
在使用 fgets()
、gets()
和 scanf()
函数时,我们需要注意它们之间的交互作用,特别是输入顺序。为了避免上述问题,我们可以在 fgets()
或 gets()
函数后立即使用 getchar()
函数读取缓冲区中的换行符,或者使用 scanf()
函数代替 fgets()
或 gets()
函数,以避免遗留的换行符导致 scanf()
函数无法如预期工作。