跨平台换行混乱

时间:2011-11-07 07:55:06

标签: c++ c text newline

出于某种原因,我的写文本文件功能突然停止工作。

void write_data(char* filename, char* writethis)
{
    ofstream myfile;
    myfile.open (filename, std::ios_base::app);
    myfile << endl << writethis;
    myfile.close();
}

该函数是从循环中调用的,所以基本上它以空行开头,并在新行上附加所有以下“writethis”行。

然后突然间,没有更多的新行。所有文本都附加在一行上。所以我做了一些挖掘,我遇到了这个:

  1. Windows = CR LF
  2. Linux = LF
  3. MAC&lt; 0SX = CR
  4. 所以我将行改为

    myfile << "\r\n" << writethis;
    

    它再次起作用。但现在我很困惑。我正在使用 linux 进行编码,但是在使用 filezilla 传输后,我正在阅读使用 windows 上的程序创建的文本文件。现在哪一部分导致文本文件中的行显示为一行?

    我非常确定“endl”对linux工作得很好所以现在我认为Windows在使用filezilla传输之后搞乱了文件?弄乱文本文件写入(和读出)的方式将保证我的程序中断,所以如果有人可以解释这一点,我会很感激。

    我也不记得我在程序中改变了什么导致它破坏,因为它之前工作得很好。我添加的唯一内容是线程。

    修改 我尝试从ASCII / Binary交换传输模式(甚至删除了force-ASCII-for-txt-extension),但没有区别。换行符出现在linux中,但不出现在Windows上。 fz-messup

    有多奇怪。

4 个答案:

答案 0 :(得分:10)

您会编写Unix行结尾('\ n'),然后将其传输到Windows计算机获取按位相同的文件,然后尝试使用不了解Unix行结尾的查看器打开文件(记事本可能)。

根据我编写可移植代码的经验:

  • 在所有平台上标准化一行结尾('\n',LF)。
  • 即使您撰写文本,也始终以二进制文件打开文件。
  • 让打开文件的用户使用能够理解任何行结尾的文本查看器。 Windows有很多(包括Visual Studio,Notepad ++,Wordpad和您最喜欢的浏览器)。

是的,我确实认为每个人都有standardize on one thing的好处,而不是支持所有人。此外,我否认在适当的平台上存在“正确的行结尾”。事实上,微软决定他们的原生API不会说UTF-8或者不理解Unix行结尾,这并不能阻止每个人的代码在Windows上这样做。请确保不要将此内容传递给WinAPI。很多时候你对系统内部数据进行文本处理是系统无法看到的,那么为什么你需要通过满足系统内部的期望来使你的生活复杂化呢?

答案 1 :(得分:6)

endl “适用于Linux”。流endl流式传输\n字符并刷新流。总是

但是,文本模式下的文件流会在Windows上的实现层将此\n转换为\r\n,并且当您在平台之间传输文件时,您经常会发现要转换的行结尾,太

这可能不是C ++问题,没有任何“破坏”;您应该将FileZilla配置为将文件视为 text 而不是“ binary ”(一种不转换行结尾的模式)。如果您的文件没有像“.txt”这样的名称扩展名,那么默认情况下它可能不会这样做。

答案 2 :(得分:3)

如果您将文件作为ASCII传输,则FTP可能会弄乱您的文件(即,它会转换换行符)。尝试转移为BIN(二进制)。

答案 3 :(得分:2)

在内部,所有应用程序都使用'\ n'来表示行终止。

问题是线路终止序列是针对文本文件的平台(随着您的研究出现)注意:文本文件,这是打开文件时的默认格式。如果在打开文件时明确选择二进制文件,则在读/写时不会发生翻译。

这实际上意味着当您将'\ n'字符写入文件时,它会转换为特定于平台的字符序列。但请注意,当读取文件时,此平台特定序列将转换回'\ n'。您遇到的问题是您已将文件写入一个平台并在另一个平台上阅读。

在linux上,行终止序列是LF('\ n')。因此,您编写文件并将所有'\ n'转换为'LF'字符。您将这些文件传输到Windows系统,现在读取该文件。在Windows上,行终止序列是'CRLF'因此,读取该文件的编辑器正在查找两个字符以转换回'\ n',但找不到这些字符。现在它取决于编辑器对于您是获得单行还是多行而言有多聪明。