C语言将标准输入内容存入数组/缓冲区的方法及代码问题求助
问题分析与解决思路
我来帮你拆解下代码里的问题,你遇到的读取失败主要有三个关键原因:
1. 未将输入指针重置到开头
你用fseek(stdin, 0, SEEK_END)定位到标准输入末尾获取了文件大小num,但此时输入流的指针已经停在末尾了。不管你用read还是fread,从这个位置开始读取都只会得到空内容——这是最核心的问题。
解决办法:在计算完num后,立刻调用rewind(stdin)或者fseek(stdin, 0, SEEK_SET)把指针移回输入流的开头。
2. 混用stdio库函数与系统调用
你同时使用了stdio库的fseek/ftell和系统调用read,这两个接口维护的是独立的缓冲区和文件偏移量,很容易出现偏移不同步的情况。比如fseek移动了stdio的指针,但read使用的是内核维护的文件偏移量,两者可能不匹配。
解决办法:统一使用一套IO接口——要么全用stdio库函数(fseek/ftell/fread),要么全用系统调用(lseek/read)。
3. read返回值的判断逻辑完全反了
你的代码里写了:
if((resRead = read(STDIN_FILENO,buffer,num))){ fprintf(stderr, "Error: Could not store the input into buffer\n"); }
但read的返回规则是:
- 返回>0:成功读取的字节数
- 返回0:已经读到输入流末尾
- 返回-1:读取错误
也就是说,你现在的逻辑是读取成功时反而打印错误,这完全搞反了!正确的判断应该是检查返回值是否等于-1(表示读取失败),或者是否小于num(表示未读取到预期的全部内容)。
修正后的代码示例(使用stdio库)
这个版本更符合C语言常规的文件操作习惯:
#include <stdio.h> #include <stdlib.h> int main() { int num; // 定位到输入末尾获取大小 if (fseek(stdin, 0, SEEK_END) != 0) { fprintf(stderr, "Error: Failed to seek to end of stdin\n"); return 1; } num = ftell(stdin); if (num == -1) { fprintf(stderr, "Error: Failed to get input size\n"); return 1; } if (num > 0) { // 重置指针到输入开头 rewind(stdin); // 分配缓冲区(额外+1是为了存放字符串结束符,可选) char *buffer = malloc(num + 1); if (!buffer) { fprintf(stderr, "Error: Out of memory\n"); return 1; } // 读取全部内容 size_t read_bytes = fread(buffer, 1, num, stdin); if (read_bytes != num) { fprintf(stderr, "Error: Only read %zu bytes out of %d\n", read_bytes, num); free(buffer); return 1; } // 可选:添加字符串结束符,方便后续当作字符串处理 buffer[num] = '\0'; // 输出缓冲区内容 for (int i = 0; i < num; ++i) { printf("%c\n", buffer[i]); } free(buffer); } return 0; }
另一个版本(使用系统调用)
如果偏好直接用系统调用操作:
#include <unistd.h> #include <stdlib.h> #include <stdio.h> int main() { off_t num = lseek(STDIN_FILENO, 0, SEEK_END); if (num == -1) { fprintf(stderr, "Error: Failed to get stdin size\n"); return 1; } if (num > 0) { // 重置偏移到输入开头 if (lseek(STDIN_FILENO, 0, SEEK_SET) == -1) { fprintf(stderr, "Error: Failed to seek to start of stdin\n"); return 1; } char *buffer = malloc(num + 1); if (!buffer) { fprintf(stderr, "Error: Out of memory\n"); return 1; } ssize_t read_bytes = read(STDIN_FILENO, buffer, num); if (read_bytes == -1) { fprintf(stderr, "Error: Failed to read from stdin\n"); free(buffer); return 1; } if (read_bytes != num) { fprintf(stderr, "Warning: Only read %zd bytes out of %zd\n", read_bytes, num); } buffer[num] = '\0'; for (int i = 0; i < num; ++i) { printf("%c\n", buffer[i]); } free(buffer); } return 0; }
内容的提问来源于stack exchange,提问作者MaxUt
相关产品推荐
相关产品推荐

