考虑这个(C99)代码:
#include <stdio.h>
int main(void)
{
char buffer[256];
while (scanf("%255[^\n]", buffer) == 1)
printf("Found <<%s>>\n", buffer);
int c;
if ((c = getchar()) != EOF)
printf("Failed on character %d (%c)\n", c, c);
return(0);
}
When I run it and type in a string 'absolutely anything with spaces TABTABtabs galore!', it gives me:
Found <<absolutely anything with spaces tabs galore!>>
Failed on character 10 (
)
ASCII (UTF-8) 1010 is newline, of course.
这有助于您理解您的问题吗?
它在这种情况下有效(对于单行),但如果我想将多行输入放入数组数组中,那么它会失败。我不明白怎么办scanf
在您的代码中返回一个值?
许多(大多数?)经验丰富的 C 程序员避免使用 C 语言是有原因的scanf()
and fscanf()
像瘟疫一样;他们很难正常工作。我推荐这个替代方案,使用sscanf()
,这并没有得到同样的咒骂scanf()
and fscanf()
do.
#include <stdio.h>
int main(void)
{
char line[256];
char sen[256];
while (fgets(line, sizeof(line), stdin) != 0)
{
if (sscanf(line, "%255[^\n]", sen) != 1)
break;
printf("Found <<%s>>\n", sen);
}
int c;
if ((c = getchar()) != EOF)
printf("Failed on character %d (%c)\n", c, c);
return(0);
}
这会读取输入行(使用fgets()
这确保没有缓冲区溢出(假装gets()
功能,如果您听说过它,会将您的计算机熔化成金属和硅池),然后使用sscanf()
处理该行。这涉及换行符,这是原始代码的失败。
char sen[20];
for (i=0;i<2;i++)
{
scanf("%[^\n]s",sen);
printf("%s\n",sen);
}
问题:
- 你不检查是否
scanf()
成功了。
- 在第一次迭代时将换行符留在缓冲区中;第二次迭代生成返回值 0,因为要读取的第一个字符是换行符,该字符是扫描集排除的字符。
- 您看到的乱码可能是重复的第一行输入。事实上,如果不是有界循环,它不会等你再输入任何内容;它会一遍又一遍地吐出第一行。
返回值来自scanf()
的定义scanf()
(来自 ISO/IEC 9899:1999)是:
§7.19.6.4 scanf 函数
Synopsis
#include <stdio.h>
int scanf(const char * restrict format, ...);
描述
2 The scanf
函数相当于fscanf
与论证stdin
介入
在参数之前scanf
.
Returns
3 The scanf
如果之前发生输入失败,函数返回宏 EOF 的值
任何转换。否则,scanf
函数返回输入项的数量
分配的数量可能少于规定的数量,如果提前分配,甚至为零
匹配失败。
请注意,当我的第一个程序中的循环退出时,这是因为scanf()
返回 0,而不是 EOF。