如何将文本文件从 DOS 格式转换为 UNIX 格式
Posted
技术标签:
【中文标题】如何将文本文件从 DOS 格式转换为 UNIX 格式【英文标题】:How to convert a text file from DOS format to UNIX format 【发布时间】:2021-12-28 00:45:51 【问题描述】:我正在尝试用 C 语言编写一个程序,该程序读取一个文本文件并将 \r\n
替换为 \n
到将行结尾从 DOS 转换为 UNIX 的同一文件。我使用fgetc
并将文件视为二进制文件。提前致谢。
#include <stdio.h>
int main()
FILE *fptr = fopen("textfile.txt", "rb+");
if (fptr == NULL)
printf("erro ficheiro \n");
return 0;
while((ch = fgetc(fptr)) != EOF)
if(ch == '\r')
fprintf(fptr,"%c", '\n');
else
fprintf(fptr,"%c", ch);
fclose(fptr);
【问题讨论】:
Windows(以及历史上的 DOS)在行尾同时使用 \r 和 \n,因此您需要删除 \r 而不是替换它。而且,不要尝试就地执行 - 制作一个单独的输出文件。 二进制?不要将 \r 替换为 \n,因为它使用 \r\n,因此您最终会得到 \n\n。您覆盖下一个字符而不是替换字符。 你不能像那样从你正在写入的同一个文件中读取。您需要两个文件指针——一个用于读取,另一个用于写入,都作为二进制文件打开。或者您可以在确保它是二进制文件流之后写信给stdout
。请注意,DOS (Windows) 文件通常在每行的末尾有 "\r\n"
;您只需要避免打印'\r'
字符。如果你遇到'\r'
后面没有'\n'
,或者'\n'
前面没有'\r'
,你会怎么做,这是任何人的猜测。我可能只是将两者都映射到'\n
。
【参考方案1】:
如果我们假设文件使用单字节字符集,那么在将文本文件从 DOS 转换为 UNIX 时,我们只需忽略所有 '\r' 字符。
我们还假设文件的大小小于最大的无符号整数。
我们做这些假设的原因是为了保持例子简短。
请注意,按照您的要求,下面的示例会覆盖原始文件。通常您不应该这样做,因为如果发生错误,您可能会丢失原始文件的内容。
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
// Return a negative number on failure and 0 on success.
int main()
const char* filename = "textfile.txt";
// Get the file size. We assume the filesize is not bigger than UINT_MAX.
struct stat info;
if (stat(filename, &info) != 0)
return -1;
size_t filesize = (size_t)info.st_size;
// Allocate memory for reading the file
char* content = (char*)malloc(filesize);
if (content == NULL)
return -2;
// Open the file for reading
FILE* fptr = fopen(filename, "rb");
if (fptr == NULL)
return -3;
// Read the file and close it - we assume the filesize is not bigger than UINT_MAX.
size_t count = fread(content, filesize, 1, fptr);
fclose(fptr);
if (count != 1)
return -4;
// Remove all '\r' characters
size_t newsize = 0;
for (long i = 0; i < filesize; ++i)
char ch = content[i];
if (ch != '\r')
content[newsize] = ch;
++newsize;
// Test if we found any
if (newsize != filesize)
// Open the file for writing and truncate it.
FILE* fptr = fopen(filename, "wb");
if (fptr == NULL)
return -5;
// Write the new output to the file. Note that if an error occurs,
// then we will lose the original contents of the file.
if (newsize > 0)
count = fwrite(content, newsize, 1, fptr);
fclose(fptr);
if (newsize > 0 && count != 1)
return -6;
// For a console application, we don't need to free the memory allocated
// with malloc(), but normally we should free it.
// Success
return 0;
// main()
只删除 '\r' 后跟 '\n' 用这个循环替换循环:
// Remove all '\r' characters followed by a '\n' character
size_t newsize = 0;
for (long i = 0; i < filesize; ++i)
char ch = content[i];
char ch2 = (i < filesize - 1) ? content[i + 1] : 0;
if (ch == '\r' && ch2 == '\n')
ch = '\n';
++i;
content[newsize++] = ch;
【讨论】:
"我们只需要忽略所有的 '\r' 字符" -- 值得商榷。这假定不会出现'\r'
字符,除非紧接在'\n'
之前。对于以与 C 实现的运行时字符集一致的单字节编码编码的 Windows 文本文件,这是一个相对安全的选择,但在技术上并不正确。
另外,将整个文件读入内存是很糟糕的形式。
@JohnBollinger 这取决于文件大小和默认块大小,问题是关于将换行符从 DOS 转换为 UNIX。如果他想回答几个问题,他应该创建更多问题。
@JohnBollinger 同意删除“\r”。我遇到的带有单独的 '\r' 字符的 DOS 文本文件通常用于打印到旧打印机上,在旧打印机上你会覆盖同一行两次,通常用于下划线或创建粗体文本。我还看到它用于在显示器上为文本加下划线。但我已经 25 年没有在野外看到它了。
添加了 sn-p 以显示如何仅替换 '\r' 后跟 '\n'。以上是关于如何将文本文件从 DOS 格式转换为 UNIX 格式的主要内容,如果未能解决你的问题,请参考以下文章
linux下安装dos2unix--将DOS格式文本文件转换成UNIX格式