在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
相关产品推荐
相关产品推荐

