1、常见问题场景
如果在输入时按下回车键,scanf
可能会跳过某些输入。由于当输入 str
时,scanf("%s", str)
会读取输入直到遇到空白字符(如空格或回车)。回车(\n
)或其他未读取的字符会残留在缓冲区中,导致后续的 scanf("%d", &num)
直接读取缓冲区的残余内容,而不是等待新的输入。
#include <stdio.h>
int main() {
char str[10];
int num;
while (1) {
printf("Enter a string and a number: ");
scanf("%s", str); // 读取字符串
scanf("%d", &num); // 读取整数
printf("You entered: %s and %d\n", str, num);
}
return 0;
}
问题原因:scanf
会处理缓冲区中的内容,但不会自动丢弃换行符(\n
)或空白字符,除非显式处理。换行符会留在缓冲区中,影响下一次读取。
2、解决方法
为了解决 scanf
跳过输入的问题,可以参考下面方法。
1)清空输入缓冲区
在每次调用 scanf
后,手动清空输入缓冲区。
#include <stdio.h>
int main() {
char str[10];
int num;
while (1) {
printf("Enter a string and a number: ");
scanf("%s", str);
while (getchar() != '\n'); // 清空缓冲区
scanf("%d", &num);
while (getchar() != '\n'); // 清空缓冲区
printf("You entered: %s and %d\n", str, num);
}
return 0;
}
2)在格式化字符串中显式处理换行符
通过 scanf
的格式化字符串来忽略空白字符或换行符。
#include <stdio.h>
int main() {
char str[10];
int num;
while (1) {
printf("Enter a string and a number: ");
scanf("%s", str); // 读取字符串
scanf(" %d", &num); // 注意前面的空格,忽略缓冲区中的换行符
printf("You entered: %s and %d\n", str, num);
}
return 0;
}
3)使用 fgets 代替 scanf
fgets
比 scanf
更安全且容易处理换行符。可以用 fgets
读取整行输入,再通过 sscanf
提取具体数据。
#include <stdio.h>
#include <stdlib.h>
int main() {
char input[100];
char str[10];
int num;
while (1) {
printf("Enter a string and a number: ");
if (fgets(input, sizeof(input), stdin) != NULL) {
// 从输入中解析字符串和整数
if (sscanf(input, "%s %d", str, &num) == 2) {
printf("You entered: %s and %d\n", str, num);
} else {
printf("Invalid input. Please try again.\n");
}
}
}
return 0;
}