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

在C语言中使用read()读取文件时如何跳过空格?

解决用read()读取文件时跳过空格解析内容的问题

看起来你现在的代码有几个基础问题,导致输出乱码,而且没实现跳过空格读取字段的需求。咱们一步步来解决:

先修正当前代码的基础错误

你的代码里data变量未定义,且输出时误用sizeof(data)——read()返回的bytes_read才是实际读取的字节数,用sizeof会输出数组里未初始化的垃圾数据。先把基础代码改对:

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

#define BUFFER_SIZE 8

void FileWork(char * fname) {
    ssize_t bytes_read;
    int fd = open(fname, O_RDONLY); // O_RDONLY模式下第三个参数无效,可省略
    if(fd == -1) {
        perror("File Error");
        exit(EXIT_FAILURE);
    }

    char data[BUFFER_SIZE + 1]; // 多留一个位置存字符串终止符
    int count =8; // testing
    while(count != 0 && (bytes_read = read(fd, data, BUFFER_SIZE)) > 0) {
        printf("\nCount = %d\n",count);
        data[bytes_read] = '\0'; // 添加终止符避免乱码
        printf("%s", data); // 直接输出字符串更安全
        count --;
    }

    close(fd); // 务必关闭文件描述符,避免资源泄漏
}

修正后代码不会输出乱码,但还是没处理空格分割的内容。接下来解决跳过空格读取下一段内容的核心需求。

方法1:逐个字符读取,精准处理字段

因为你的文件内容是空格分隔的字段(比如hello、1100011这类),可以逐个读取字符:先跳过所有空格,再读取直到下一个空格或文件结束,这样就能拿到每个独立字段:

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <ctype.h> // 用于isspace()判断空白字符

#define FIELD_BUFFER 64 // 定义单个字段的最大长度

void read_field(int fd, char *buffer, size_t buf_size) {
    char c;
    ssize_t ret;

    // 第一步:跳过所有空白字符(空格、换行、制表符等)
    while((ret = read(fd, &c, 1)) > 0 && isspace((unsigned char)c)) {
        // 仅跳过,不做其他操作
    }

    if(ret <= 0) {
        buffer[0] = '\0'; // 已到文件结尾
        return;
    }

    // 第二步:读取当前字段,直到遇到空白字符或文件结束
    size_t idx = 0;
    buffer[idx++] = c; // 先存入刚才读到的第一个非空白字符
    while(idx < buf_size -1 && (ret = read(fd, &c, 1)) > 0 && !isspace((unsigned char)c)) {
        buffer[idx++] = c;
    }
    buffer[idx] = '\0'; // 添加字符串终止符
}

void FileWork(char * fname) {
    int fd = open(fname, O_RDONLY);
    if(fd == -1) {
        perror("File Error");
        exit(EXIT_FAILURE);
    }

    char field[FIELD_BUFFER];
    printf("读取的字段列表:\n");
    while(1) {
        read_field(fd, field, sizeof(field));
        if(field[0] == '\0') {
            break; // 无更多字段可读取
        }
        printf("- %s\n", field);
    }

    close(fd);
}

这个方法逻辑简单直观,能精准处理每个字段,自动跳过所有空白字符。

方法2:缓冲区批量读取(适合大文件,提升效率)

如果文件很大,逐个字符读取会频繁调用read(),效率偏低。可以先读取一块缓冲区,再在缓冲区内部解析字段、跳过空格:

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

#define BUFFER_SIZE 256
#define FIELD_BUFFER 64

void FileWork(char * fname) {
    int fd = open(fname, O_RDONLY);
    if(fd == -1) {
        perror("File Error");
        exit(EXIT_FAILURE);
    }

    char buffer[BUFFER_SIZE];
    ssize_t bytes_read;
    size_t buf_pos = 0; // 当前缓冲区的读取位置
    char field[FIELD_BUFFER];

    printf("读取的字段列表:\n");

    while((bytes_read = read(fd, buffer + buf_pos, BUFFER_SIZE - buf_pos)) > 0) {
        size_t total_bytes = buf_pos + bytes_read;
        size_t i = 0;

        while(i < total_bytes) {
            // 跳过空白字符
            while(i < total_bytes && isspace((unsigned char)buffer[i])) {
                i++;
            }
            if(i >= total_bytes) break;

            // 读取单个字段
            size_t field_idx = 0;
            while(i < total_bytes && !isspace((unsigned char)buffer[i]) && field_idx < FIELD_BUFFER -1) {
                field[field_idx++] = buffer[i++];
            }
            field[field_idx] = '\0';
            printf("- %s\n", field);
        }

        // 把缓冲区未处理的剩余字符移到开头,供下一次读取使用
        buf_pos = total_bytes - i;
        if(buf_pos > 0) {
            for(size_t j=0; j<buf_pos; j++) {
                buffer[j] = buffer[i + j];
            }
        }
    }

    close(fd);
}

这个方法减少了系统调用次数,适合处理大文件,效率更高,只是逻辑稍复杂。

额外提醒

  • 始终要记得调用close(fd)关闭文件描述符,避免资源泄漏
  • read()返回-1表示出错,返回0表示文件结束,这两种情况都要妥善处理
  • 如果字段长度可能超过你定义的缓冲区大小,建议用realloc()动态分配内存,避免缓冲区溢出

希望这些方案能帮到你!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 15:52:33