在典型的 scanf() 调用中不会使用换行符
当这个程序
#include <stdio.h>
#include <string.h>
int main(void) {
int num = 0;
char str[128], *lf;
scanf("%d", &num);
fgets(str, sizeof(str), stdin);
if ((lf = strchr(str, '\n')) != NULL) *lf = '\0';
printf("%d \"%s\"\n", num, str);
return 0;
}
使用此输入执行
42
life
输出将是 42 ""
而不是预期的 42 "life"
。
这是因为在 scanf()
的调用中没有消耗 42
之后的换行符,并且在读取 life
之前它被 fgets()
使用。然后,fgets()
在阅读 life
之前停止阅读。
为了避免这个问题,在知道线的最大长度 - 例如在线判断系统中解决问题时 - 有用的一种方法是避免直接使用 scanf()
并通过 fgets()
读取所有线。你可以使用 sscanf()
来解析读取的行。
#include <stdio.h>
#include <string.h>
int main(void) {
int num = 0;
char line_buffer[128] = "", str[128], *lf;
fgets(line_buffer, sizeof(line_buffer), stdin);
sscanf(line_buffer, "%d", &num);
fgets(str, sizeof(str), stdin);
if ((lf = strchr(str, '\n')) != NULL) *lf = '\0';
printf("%d \"%s\"\n", num, str);
return 0;
}
另一种方法是在使用 scanf()
之后和使用 fgets()
之前读取直到你击中换行符。
#include <stdio.h>
#include <string.h>
int main(void) {
int num = 0;
char str[128], *lf;
int c;
scanf("%d", &num);
while ((c = getchar()) != '\n' && c != EOF);
fgets(str, sizeof(str), stdin);
if ((lf = strchr(str, '\n')) != NULL) *lf = '\0';
printf("%d \"%s\"\n", num, str);
return 0;
}