【问题标题】:Replace CR LF with LF in C用 C 中的 LF 替换 CR LF
【发布时间】:2017-12-11 20:44:11
【问题描述】:

我必须编写一个功能类似于 dos2unix 的 C 程序。将所有 CR LF 替换为仅 LF(DOS 格式到 Unix 格式)。 所以这是我的方法。每次我读到一行,我通过查找\0来搜索数据的结尾,然后检查以下是否为\r\n。 如果是,则替换为 \nonly。但它似乎不起作用,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
}

【问题讨论】:

  • 您需要使用strcmp(或strncmp)来比较字符串。 == 比较指针值。
  • 请阅读this question
  • 这不是比较字符串,而是以文本模式打开文件;它不是标记的问题/答案的副本。
  • 除了其他人指出的所有错误之外,您可能需要以二进制模式打开这两个文件("rb""wb")才能首先看到 CRLF,然后防止 C 库在输出时将\n 转换回\r\n;您没有检查任何错误;您用\n 替换 \r\n 的逻辑不正确;而且你没有正确处理长线;
  • 如果您要转换换行符,则没有充分的理由使用fgets。该功能是面向行的,如果您担心行尾,那么根据定义,您几乎不信任您的输入。而fgets 太过分了。使用fgetcgetc 一次读取文件一个字符。您只需要跟踪少量的状态。 (有两种状态:一种是之前读取的字符是\r,一种不是)

标签: c newline carriage-return


【解决方案1】:

你有一大堆错误:

  • 您可能需要在"rb" 模式下打开in.txt,而不是"r" 模式,才能首先看到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 和裸\r 都转换为\n,因为裸\r 现在非常罕见,但在某些历史操作系统(尤其是经典操作系统)上用作行终止符MacOS),并且没有其他任何明智的做法。

重要的是cint,而不是char,这样它就可以包含EOF 以及所有可能的字符。

【讨论】:

  • 注意;回复:“您不检查 I/O 错误。”此代码确实检查输入错误。它不检查输出错误(这种情况很少见)。
  • @chux 根据我的经验,我的主要意思是他们没有检查fopen 的结果。
猜你喜欢
  • 2016-05-09
  • 1970-01-01
  • 2016-03-28
  • 2011-06-03
  • 2012-07-05
  • 2010-12-04
  • 1970-01-01
  • 2019-03-14
相关资源
最近更新 更多