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

如何仅使用read(2)和write(2)系统调用改写实现类head命令的C代码

基于read/write系统调用实现类head命令的代码调整方案

直接替换为read/write后输出整个文件的核心原因:fgets是标准库封装的按行读取接口,会自动识别换行符做行截断,但read系统调用仅按字节读取内容,没有行逻辑,你需要自行实现换行符统计,达到指定行数后终止读取输出即可。

完整实现代码

#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>

#define BUFFSIZE 10000

int main (int argc, char* argv[]) {
    // 简单参数校验,用法示例:./myhead -n 5 test.txt
    if (argc != 4) {
        char usage[] = "Usage: ./myhead -n <输出行数> <目标文件路径>\n";
        write(STDERR_FILENO, usage, sizeof(usage)-1);
        exit(1);
    }

    int line_limit = atoi(argv[2]);
    if (line_limit <= 0) {
        char err[] = "输出行数必须为正整数\n";
        write(STDERR_FILENO, err, sizeof(err)-1);
        exit(1);
    }

    int fd = open(argv[3], O_RDONLY);
    if (fd < 0) {
        char err[] = "文件打开失败\n";
        write(STDERR_FILENO, err, sizeof(err)-1);
        exit(1);
    }

    char buffer[BUFFSIZE];
    ssize_t read_bytes;
    int line_count = 0;
    int output_pos = 0;

    while ((read_bytes = read(fd, buffer, BUFFSIZE)) > 0) {
        // 逐字节遍历当前缓冲区内容,统计换行
        for (int i = 0; i < read_bytes; i++) {
            if (buffer[i] == '\n') {
                line_count++;
                // 达到行数上限,输出到当前换行符位置后终止
                if (line_count == line_limit) {
                    write(STDOUT_FILENO, buffer + output_pos, i - output_pos + 1);
                    goto end_process;
                }
            }
        }
        // 缓冲区未触发行数上限,全部输出
        write(STDOUT_FILENO, buffer + output_pos, read_bytes - output_pos);
    }

end_process:
    close(fd);
    return 0;
}

核心逻辑说明

  • 用open()系统调用替代fopen(),返回的整数文件描述符替代标准库的FILE*指针,打开模式指定O_RDONLY只读即可
  • 每次调用read()读取最多BUFFSIZE字节的内容到缓冲区,逐字节遍历检查换行符\n
  • 每识别到一个换行符就累加行计数,达到指定行数时输出当前位置到换行符的内容后直接终止流程
  • 输出全部使用write()写入到STDOUT_FILENO(标准输出的固定文件描述符为1),完全不依赖标准IO库函数
  • 流程结束前调用close()关闭文件描述符,避免资源泄漏

内容的提问来源于stack exchange,提问作者Belle247

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 21:54:02