考虑一下这个 (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);
}
当我运行它并输入一个字符串“绝对是任何带有空格 TABTABtabs galore!”的字符串时,它给了我:
Found <<absolutely anything with spaces tabs galore!>>
Failed on character 10 (
)
ASCII (UTF-8) 1010 当然是换行符。
这是否有助于您理解您的问题?
它在这种情况下有效(对于单行),但如果我想将多行输入放入一个数组数组中,那么它会失败。而且我不明白scanf 如何在您的代码中返回值?
许多(大多数?)有经验的 C 程序员避免 scanf() 和 fscanf() 是有原因的;他们很难正常工作。我推荐这个替代方案,使用sscanf(),它不会得到与scanf() 和fscanf() 相同的执行。
#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 函数
概要
#include <stdio.h>
int scanf(const char * restrict format, ...);
说明
2 scanf 函数等效于 fscanf 插入参数 stdin
在scanf 的参数之前。
返回
3 如果之前发生输入失败,scanf 函数会返回宏 EOF 的值
任何转换。否则,scanf 函数返回输入项的数量
分配的,这可能比规定的要少,甚至为零,如果提前
匹配失败。
请注意,当我的第一个程序中的循环退出时,这是因为 scanf() 返回 0,而不是 EOF。