【发布时间】:2021-09-06 07:37:46
【问题描述】:
在 scanf() 之后使用 fgets() 时,我试图解决换行缓冲区问题,我最初的解决方案是使用 scanf("\n"); 使用换行符。它解决了这个问题,但后来我遇到了一个不同的解决方案,用 scanf("%c ",&ch); 消耗缓冲区中的换行符;
注意:%c 后面有个空格确实解决了问题
这是导致换行缓冲区问题的完整代码:
#include "stdio.h"
int main() {
char ch;
char s[100];
char sen[100];
scanf("%c", &ch);
scanf("%s", s);
fgets(sen, sizeof(sen), stdin);
printf("%c\n", ch);
printf("%s\n", s);
puts(sen);
return 0;
}
但是在 %c 和 %s 之后添加空格时,相同的代码将起作用,如下所示:
#include "stdio.h"
int main() {
char ch;
char s[100];
char sen[100];
scanf("%c ", &ch);
scanf("%s ", s);
fgets(sen, sizeof(sen), stdin);
printf("%c\n", ch);
printf("%s\n", s);
puts(sen);
return 0;
}
我的问题是 %c 和 %s 之后的两个空格是如何消耗换行符以使 fgets() 能够接受输入的?
【问题讨论】:
-
这是设计使然:这是
scanf格式字符串中的空格的目的 - 在输入流中消耗 任意数量 的空格,尽管某些说明符会这样做它自动。该字符串中的每个字符都是格式的一部分。请参阅scanf() leaves the newline char in the buffer。但一般来说,将任何空格放在格式字符串的末尾是个坏主意,因为只有在输入流中存在另一个非空格字符时才会满足要求,该字符将保留在那里。 -
“解决”这个问题的最好方法是不要混合scanf和fgets。他们真的不能一起玩。
-
如果您只是必须将两者混合,通常的解决方案是使用内联代码,或者可能是集中的“gobble”函数,读取字符直到(包括)换行符,然后插入此代码/call 必要时,通常在
scanf调用之后和fgets调用之前。 -
有关不使用
scanf的帮助,请参阅this question。 -
@WeatherVane 我想说,如果您希望能够输入带空格的字符串,是时候停止使用
scanf和start usingfgetsfor everything。scanf唯一的优点是它对初学者来说简单易用。但是%[]与 simple'n'easy 正好相反。