fgets是否总是从字符串开头读取?循环读取多行标准输入的方法
用fgets读取标准输入多行内容的问题
疑问解答:for循环中调用fgets会不会每次读第一行?
不会。标准输入stdin是一个顺序字节流,每次调用fgets成功读取一行后,流的内部位置指针会自动移动到下一行的起始位置,下一次调用fgets会从当前位置继续读取,而非从头开始。只有当你手动调用rewind(stdin)或fseek(stdin, 0, SEEK_SET)重置流指针时,才会回到开头重新读取第一行。
正确的多行读取实现
1. 读取到流结束(EOF)
当用户输入结束(Unix/Linux按Ctrl+D,Windows按Ctrl+Z),fgets会返回NULL,以此作为循环终止条件:
#include <stdio.h> #include <stdlib.h> #define BUFFER_SIZE 1024 int main() { char buffer[BUFFER_SIZE]; // for循环持续读取,直到fgets返回NULL(EOF或读取错误) for (; fgets(buffer, BUFFER_SIZE, stdin) != NULL; ) { // 处理读取到的内容,这里以输出为例 printf("读取到:%s", buffer); } // 检查是否因读取错误退出 if (ferror(stdin)) { perror("读取标准输入出错"); exit(EXIT_FAILURE); } return 0; }
2. 读取指定行数
如果需要读取固定行数的内容,可以在for循环中加入行数计数:
#include <stdio.h> #include <stdlib.h> #define BUFFER_SIZE 1024 #define TARGET_LINES 3 int main() { char buffer[BUFFER_SIZE]; int line_num; for (line_num = 0; line_num < TARGET_LINES; line_num++) { if (fgets(buffer, BUFFER_SIZE, stdin) == NULL) { // 提前遇到EOF或错误,终止循环 break; } printf("第%d行:%s", line_num + 1, buffer); } if (ferror(stdin)) { perror("读取标准输入出错"); exit(EXIT_FAILURE); } return 0; }
注意事项
fgets会把换行符\n也读取到缓冲区中,如果不需要换行符,可以手动去除:buffer[strcspn(buffer, "\n")] = '\0';- 如果输入行长度超过
BUFFER_SIZE-1,fgets会截断该行,剩余内容会留在输入流中,下一次调用fgets会继续读取剩余部分。 - 不要随意重置
stdin的位置指针,否则会导致重复读取之前的内容。
内容的提问来源于stack exchange,提问作者jacob87
相关产品推荐
相关产品推荐

