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; }