我必须编写一个功能类似于 dos2unix 的 C 程序。它将所有 CR
LF
替换为仅 LF
(DOS 格式到 Unix 格式)。
所以这是我的方法。每次我读一行时,我通过查找 \0
来搜索数据的结尾,然后检查以下是否是 \r\n
。
如果是,仅替换为 \n
。但它似乎不起作用,CRLF here
行从未打印过一次。
char data[255]; // save the data from in.txt
char *checker;
pf = fopen("in.txt", "r");
pf2 = fopen("out.txt", "w");
while (feof(pf) == 0)
{
fgets(data, 255, pf); // Read input data
checker = data;
while (checker != "\0") // Search for a new line
{
if (checker == "\r\n") // Check if this is CR LF
{
printf("CRLF here");
checker = "\n"; // replace with LF
}
checker++;
}
fputs(data, pf2); // Write to output data
}
最佳答案
你有一大堆错误:
- 您可能需要以
"rb"
模式而不是"r"
模式打开in.txt
,以查看CRLF 行首先是结局。 - 您可能需要以
"wb"
模式而不是"w"
模式打开out.txt
,以防止C 库从撤消你的工作。 - 您不能将字符串文字与
==
进行比较。您可以使用==
将字符串的一个字符与字符 文字进行比较,但这不是您正在做的,它只起作用对于单个字符; CRLF 序列是两个 个字符。 - 您不能通过简单赋值在可变 C 字符串中用单字符序列替换双字符序列。您需要使用
memmove
将替换后的所有字符向下移动一个。 - 您没有正确处理很长的行。
- 您不检查
fopen
是否成功,或任何其他 I/O 错误。 -
while (!feof (fp))
is always wrong .
编写这个程序的更好方法是使用一个一个字符一个字符的主循环,类似于
int c;
while ((c = getc(ifp)) != EOF) {
if (c == '\r') {
putc('\n', ofp);
c = getc(ifp);
if (c == EOF) break;
if (c == '\n') continue;
}
putc(c, ofp);
}
这会将 \r\n
和 bare \r
都转换为 \n
,因为 bare \r
现在非常罕见,但被用作某些历史操作系统(尤其是经典的 MacOS)的行终止符,并且没有任何其他明智的做法。
重要的是 c
是 int
,而不是 char
,这样它可以容纳 EOF 以及所有可能的字符。
关于c - 用 C 中的 LF 替换 CR LF,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47761108/