You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:12:39