【问题标题】:Is there a "preferred_end_of_line_separator" in file i/o operations in C++17 or C++20?在 C++17 或 C++20 的文件 i/o 操作中是否有“preferred_end_of_line_separator”?
【发布时间】:2025-11-25 21:15:01
【问题描述】:

当我尝试操作文本文件时,我希望将行尾字符设置为目标操作系统上的首选字符,例如 linux 文本文件中的 LF 和 windows 文本文件中的 CRLF。

相关问题

根据问题C++: Is there a standard definition for end-of-line in a multi-line string constant?,eol 字符取决于源文件中的字符。这意味着,当我使用

std::ofstream out{"hello.txt"};
out << R"(Hello
World)" << std::endl;

“hello.txt”中的 eol 字符映射到单个 '\n' 字符,即使源文件以 Windows 文本格式存储。

根据问题Detect Windows or Linux in C, C++Standard #ifdef for Cygwin,我可以用

#if defined(_WIN32) || defined(__CYGWIN__)
#define END_OF_LINE "\n\r"
#else
#define END_OF_LINE "\n"

但是,我不知道如何将这些代码放入之前的代码段中。

Java 解决方案

在java中,使用

System.getProperty("line.separator");

将返回相应的行尾字符。

JDK 7 将上述行替换为System.lineSeparator(),效率更高。

C++ 解决方案?

C++17 文件系统提供了一个常量:std::filesystem::path::preferred_separator 来告诉各种操作系统平台上的路径分隔符。我认为这是一个很好的形式。

在 C++17 或更新的标准中是否有任何现有的工具可以提供std::xxx::preferred_eol_separator 这样的便利?

【问题讨论】:

  • @Nicol Bolas 我犯了一个错误。改正后。谢谢。

标签: c++17


【解决方案1】:

是的,很有趣——它叫做'\n'。原因是,标准库(printf()s、couts 及其家族)的输出 I/O 操作中对 NEW LINE 字符的解释取决于您如何打开文件进行写入。例如

fopen("path", "w");

在 POSIX 上将文件标记为“可写文件”,在 Windows 上将其标记为“可写文本文件”。 POSIX 不会翻译输入缓冲区的内容,而在 Windows 上,每个 '\n' 都将存储为 CRLF 对。另一方面,

fopen("path", "wb");

将文件标记为 POSIX 上的“可写文件”(再次)和 Windows 上的“可写二进制文件”。这一次,POSIX 和 Windows 都不会做任何翻译。

输入文件也会发生同样的情况:"r" 将被视为“可读文本文件”,"rb" 将被视为“可读二进制文件”,在 Windows 上,对“文本”文件的任何读取操作都会将任何 CRLF 作为单独的 \n 报告回应用程序。

这种方法也可以在 iostreams 中使用,其中所有 coutcerrclog 都被视为文本文件,而 ofstreamifstream 可以在构造函数中使用 std::ios_base::binary 标志来区分在文本和二进制模式之间。

【讨论】:

  • 您不是说“每个\n 都会被存储为一个CRLF 对”吗?
  • 是的,我做到了。感谢您发现这一点。