C11中如何用scanf()通过stdin读取文件并判断结束
解决scanf读取多行字符串时的文件结束判断问题
你遇到的核心问题是错误地将字符串与EOF进行比较——EOF是C标准库定义的int类型常量(通常值为-1),并非字符串,这种类型不匹配的判断逻辑直接导致了循环异常。
正确的scanf用法:通过返回值判断文件结束
scanf的返回值表示成功读取的变量个数,当到达文件末尾(或读取出错)时,会返回EOF。正确的循环终止条件应该是检查这个返回值,而非读取到的字符串内容。
示例代码:
#include <stdio.h> int main() { char str[256]; // 定义足够容纳单个字符串的缓冲区 // 当scanf成功读取到字符串时,返回值为1;到达EOF时返回EOF while (scanf("%s", str) != EOF) { printf("读取到:%s\n", str); } return 0; }
注:%s格式符会自动跳过换行、空格等前导空白,读取到下一个空白字符前的内容,完全适配你“每行一个字符串”的输入场景。
按行读取的替代方案(更直观处理行结构)
如果需要严格按行处理输入(比如后续有行相关的逻辑),使用fgets会更合适,同样通过返回值判断EOF:
#include <stdio.h> #include <string.h> int main() { char line[256]; // fgets读取一行内容(包括换行符),返回NULL表示到达EOF或读取失败 while (fgets(line, sizeof(line), stdin) != NULL) { // 移除末尾的换行符(如果存在) line[strcspn(line, "\n")] = '\0'; printf("读取到:%s\n", line); } return 0; }
原逻辑出错的原因
当scanf到达文件末尾时,不会向你的字符串缓冲区写入任何内容,此时缓冲区保留的是之前读取的旧值。你拿这个旧字符串和int类型的EOF比较,编译器会进行隐式类型转换,导致判断逻辑完全失效,最终陷入死循环。
内容的提问来源于stack exchange,提问作者Proth
相关产品推荐
相关产品推荐

