如何使用C语言实现DOS格式文本文件转UNIX格式
C语言DOS转UNIX行尾格式代码修复
原代码存在的问题
- 变量
ch未声明,且必须声明为int类型:fgetc返回值为int类型,包含所有unsigned char的取值范围+超出范围的EOF标识,若用char类型存储会导致EOF判断失效。 - 共享文件指针的读写逻辑错误:以
rb+打开的文件共用同一读写指针,读完一个字符后指针自动后移,此时直接写入内容会覆盖尚未读取的后续原始内容,导致数据损坏。 - 替换逻辑不符合需求:现有逻辑会将所有单独的
\r也替换为\n,DOS行尾是连续的\r\n序列,仅需将该连续序列替换为单\n即可。 - 未处理替换后文件长度缩短的问题:替换后每个行尾会减少1字节,直接改写原文件后末尾会残留无效的冗余内容。
推荐实现方案
建议先将文件内容读取处理后写入临时文件,处理完成后再覆盖原文件,逻辑更稳定不易出错,实现代码如下:
#include <stdio.h> int main() { const char *filename = "textfile.txt"; FILE *fptr = fopen(filename, "rb"); if (fptr == NULL) { printf("打开文件失败\n"); return 1; } // 创建临时文件存储处理后内容 FILE *tmp_fptr = fopen("tmp_convert.txt", "wb"); if (tmp_fptr == NULL) { printf("创建临时文件失败\n"); fclose(fptr); return 1; } int ch, next_ch; while((ch = fgetc(fptr)) != EOF) { if(ch == '\r') { // 检查下一个字符是不是\n next_ch = fgetc(fptr); if(next_ch == '\n') { // 是DOS换行,只写\n fputc('\n', tmp_fptr); } else { // 单独的\r,原样写入两个字符 fputc('\r', tmp_fptr); if(next_ch != EOF) { ungetc(next_ch, fptr); // 把多读取的字符塞回流里 } } } else { // 普通字符直接写 fputc(ch, tmp_fptr); } } fclose(fptr); fclose(tmp_fptr); // 用临时文件覆盖原文件 remove(filename); rename("tmp_convert.txt", filename); return 0; }
注意事项
- 如果确定要直接在原文件上修改,需要先读取整个文件到内存处理完成后再写回原文件,且写完后需要调用
ftruncate(POSIX系统)或_chsize(Windows)截断掉文件末尾的冗余内容。 - 处理二进制文件时使用
fputc比fprintf性能更高,更适合单字符写入场景。
内容的提问来源于stack exchange,提问作者Pedro Barata Fernandes
相关产品推荐
相关产品推荐

