流、流缓冲区、编码转换器和 \n 到 \r\n 的转换

5
C ++ IO流的哪个部分执行\r\r\n转换?是stream_buf本身还是codecvt facet的内部到外部编码转换的一部分?

更新1
你们都说是在streambuf/filebuf中完成的。好的。但是这种安排如何处理诸如UTF-16之类的外部编码?然后,似乎必须使用ios::binary标志打开文件以禁用转换。

1
这应该是\n转换为\r\n吧?通常从可移植代码中得到的是\n,你需要在“类似于Windows”的表示中添加换行符。 - πάντα ῥεῖ
在编码方面,添加额外的\r与所使用的字符编码无关,它仍然是一个额外的字符。\r控制终端写入光标以便于某些终端从第0列开始。而codecvt则控制用于编码单个字符的字节数。 - πάντα ῥεῖ
3个回答

2
这种转换通常不是由流、streambuf或facet执行的。它是由C库代码(例如fputc())负责的,该代码由streambuf的overflow()underflow()调用。
如果出于某种原因需要进行此转换(例如在实现dos2unix例程时),可以在boost.iostreams中找到一个方便的示例。
编辑:std::filebuf仅支持文本文件的多字节编码,例如UTF-8或GB18030或区域设置使用的任何编码。UTF-16文件必须以二进制模式打开,作为纯字节流(可以使用C++11的codecvt工具将其解释为UTF-16),是的,行尾不会被转换。

streambuf的实现不一定需要使用fputc(),这取决于上下文。我们有针对streambuf的实现,直接输出到UART以进行调试,所使用的(RT)OS甚至不提供文件句柄,那么如何使用fputc()呢? - πάντα ῥεῖ
@g-makulik,特别是std::cout使用的streambuf需要使用与C I/O写入stdout时相同的底层缓冲区,因此这将是非标准的。至于filebuf和其他streambufs,那就是我所说的“通常”的情况。 - Cubbi

1
据我所知,它是在streambuf实现中完成的,codecvt只处理区域设置表示特定内容。

与Éric Malenfant的回答相同:为什么要在filebuf中执行?这是否意味着filebuf必须具有codecvt facet提供的外部编码知识? - wilx
在我看来,这与字符编码无关,而是与操作系统如何处理终端显示中的行尾有关。 - πάντα ῥεῖ

1

如果没有使用ios::binary标志打开,它将由std::filebuf执行。


为什么要在filebuf中执行此操作?这是否意味着filebuf必须具有由codecvt facet提供的外部编码的某些知识? - wilx

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接