为何二进制模式写入含\r\n的文件,文本模式读取后仅保留\n?
为什么二进制模式写入"\r\n"后,文本模式读取会变成"\n"?
问题场景
在Windows环境(g++、clang、msvc)下测试以下代码:
std::ofstream out_file("1.txt", std::ios::binary); out_file.write("0\r1\r\n2", 6); out_file.close(); std::ifstream in_file("1.txt"); std::string txt{ std::istreambuf_iterator<char>(in_file), std::istreambuf_iterator<char>() }; std::cout << "txt.size() = " << txt.size() << '\n'; for (int i = 0; i < txt.size(); ++i) { std::cout << "i = " << i << " char code = " << int(txt[i]) << '\n'; }
运行后发现原本写入的\r\n在文本模式读取时变成了\n,同时补充实验发现:
- 仅使用
std::ios::binary(二进制模式)写入时,\n不会被转换; - 不使用
std::ios::binary(文本模式)写入时,\n会被转成\r\n; - 文本模式读取时,文件中的
\r\n会被转成\n。
原因解释
这是Windows系统和C++标准库针对文本文件换行处理的约定,核心是为了屏蔽不同操作系统的换行差异:
- Windows系统的文本文件换行约定:用
\r\n(回车+换行,简称CRLF)表示换行;而C++标准中,代码层面统一用\n(换行,简称LF)表示换行。 - 文本模式的自动转换逻辑:
- 写入时:标准库会把代码里的
\n自动转换成Windows系统的\r\n,确保生成的文本文件符合Windows的读取规范; - 读取时:标准库会把文件里的
\r\n自动转换成代码层面的\n,让你在代码里不用区分系统,统一用\n处理换行。
- 写入时:标准库会把代码里的
- 二进制模式的无转换逻辑:二进制模式下,标准库完全不做任何字节转换,写入的字节原封不动存在文件中,读取时也原样返回,适合处理图片、视频这类不需要换行转换的二进制数据。
你的实验结果正好对应这个逻辑:
- 二进制写入时,你写的
\r\n原封不动存在文件里; - 文本模式读取时,标准库识别到文件里的
\r\n,自动转换成\n返回给代码,所以最终字符串里只剩\n。
这种设计的本质是让C++代码在不同操作系统下处理文本文件时,不用手动适配换行符,实现跨平台的一致性。
内容的提问来源于stack exchange,提问作者Pavel
相关产品推荐
相关产品推荐

