当您希望用户输入两个单词时,您还希望能够处理用户输入一个单词的情况(可能认为他们将在下一行输入下一个单词,等等......)将scanf() 与"%s" 转换说明符一起使用的问题是它忽略了前导空格,而'\n' 字符是空格。因此,如果只输入了一个单词,您就不必提示输入第二个单词,因为scanf() 将阻止等待第二个输入。
无论何时接受用户输入,我们都鼓励您使用fgets() 填充缓冲区(字符数组),然后从缓冲区解析(分离)所需的值。为什么? fgets() 将消耗一整行输入(给定足够大小的缓冲区)。这确保了stdin 中不会有任何内容未读 --- 只是在等待下一次输入时咬你。
然后,您可以使用 sscanf() 解析缓冲区中的值,就像使用 scanf() 解析输入中的值一样。但是,您已将输入和转换解耦,因此如果 sscanf() 转换失败,它不会影响您下次尝试从 stdin 读取。
使用fgets() 还提供了一种结束输入的便捷方式。由于fgets() 读取用户按Enter 生成的'\n' 字符,因此您只需检查缓冲区中填充的第一个字符是否是'\n' 字符即可知道用户只是按了在空白行上输入。这可以用作一种非常方便的方式来确定用户是否已完成,而无需额外输入,例如strcmp(FirstWord, "quit") 等...
如果我了解您希望能够无缝处理来自用户的一两个输入并在用户只提供一个的情况下提示,您可以这样做:
#include <stdio.h>
#define WORDSZ 32 /* if you need a constant, #define one (or more) */
#define MAXC 1024
int main (void) {
char FirstWord[WORDSZ]; /* declare arrays */
char SecondWord[WORDSZ];
char buf[MAXC]; /* buffer to hold entire line */
puts ("press [Enter] on empty line when done.");
while (1) { /* loop continually until both filled or user cancels */
fputs ("\nEnter two words: ", stdout); /* prompt both */
if (fgets (buf, MAXC, stdin) == NULL) { /* read into buf, validate */
puts ("(user canceled input)");
return 0;
}
else if (*buf == '\n') /* if [Enter] on empty line */
break;
/* validate conversion, check if only one word read */
if (sscanf (buf, "%31s %31s", FirstWord, SecondWord) == 1) {
while (1) { /* if so, loop until second word read */
fputs ("Enter second word: ", stdout); /* prompt 2nd word */
if (!fgets (buf, MAXC, stdin)) { /* read into buf, validate */
puts ("(user canceled input)");
return 0;
}
if (sscanf (buf, "%31s", SecondWord) == 1) /* validate word entered */
break;
}
}
printf ("\nFirst word is %s \nSecond word is %s\n", FirstWord, SecondWord);
}
}
(注意:在使用 @987654339 时,您必须始终为所有字符串转换提供比数组大小小 1 的 field-width 修饰符,以保护数组边界@ 系列函数。否则使用scanf() 并不比使用gets() 更安全,参见Why gets() is so dangerous it should never be used!)
由于用户通过生成手动EOF 来取消输入是完全有效的,因此您需要在每次使用fgets() 读取后通过检查返回是否为NULL 来检查手动EOF。用户按 Ctrl + d(在 Windows 上为 Ctrl + z)会生成手册 EOF。
使用/输出示例
$ ./bin/firstsecondword
press [Enter] on empty line when done.
Enter two words: hello
Enter second word: world
First word is hello
Second word is world
Enter two words: hello world
First word is hello
Second word is world
Enter two words:
查看一下,如果您还有其他问题,请告诉我。