将带有 CRLF 行终止符的 Little-endian UTF-16 Unicode 英文文本文件转换为 Ascii 编码
Posted
技术标签:
【中文标题】将带有 CRLF 行终止符的 Little-endian UTF-16 Unicode 英文文本文件转换为 Ascii 编码【英文标题】:Convert file from Little-endian UTF-16 Unicode English text, with CRLF line terminators to Ascii encoding 【发布时间】:2018-03-07 10:57:29 【问题描述】:非常感谢在我之前的场景中帮助过我的每个人。我相信有人会像以前一样问过类似的问题。这是我的问题。
我的文件属于 Little-endian UTF-16 Unicode 英文文本,带有 CRLF 行终止符 编码,但我认为它不适用于我们的文件标准。通常我在这里看到的属于ASCII 英文文本。我如何将其转换为它。
我使用了iconv -f UTF-16LE -t UTF-8 myfile.dat -o myfile.dat_test
,但它正在将整个文件转换为 UTF-8 Unicode (with BOM) 英文文本,带有 CRLF 行终止符,不太清楚发生了什么。
【问题讨论】:
除了您不想要 BOM 之外一切都好吗? 最好是ASCII英文文本 如果所有字符都在 ASCII 范围内 (<= 127 or 0x7f
),UTF8 将完全等同于 ASCII。如果您的 UTF-16 包含 UTF8 编码超过一个字节的字符,则需要另一个计划。无论如何,这可能很有用:zzz.buzz/2016/07/30/bom-in-iconv
也许一个更好的问题是,如果你想要 ASCII,你为什么要告诉 iconv
转换为 UTF-8?
这可能是您输入文件的 BOM。如果是这样,请尝试将其删除。
【参考方案1】:
这里的问题是 BOM 是“UTF-16”的特征,不是“UTF-16LE”的特征。
每http://unicode.org/faq/utf_bom.html#gen7:
BE形式使用big-endian字节序列化(最高有效字节在前),LE形式使用little-endian字节序列化(最低有效字节优先),未标记形式默认使用big-endian字节序列化,但可能包括开头的字节顺序标记,表示实际使用的字节序列化。
请注意,包含字节顺序标记的选项仅适用于“未标记的形式”,即“UTF-16”。
因此,当您告诉iconv
源编码是“UTF-16LE”,然后输入以 FF FE 开头时,iconv
不会将 FF FE 解释为字节顺序的冗余指示;相反,它将其解释为 U+FEFF 零宽度无间隔空格,并尝试将该字符复制到输出。
您可以通过告诉iconv
源编码为“UTF-16”来解决此问题;然后,当它看到输入以 FF FE 开头时,会将其解释为字节顺序标记,将其删除,并将输入的其余部分解释为 little-endian。
所以,改变这个:
iconv -f UTF-16LE -t UTF-8 myfile.dat -o myfile.dat_test
到这里:
iconv -f UTF-16 -t US-ASCII myfile.dat -o myfile.dat_test
(注意:我还将 'UTF-8' 更改为 'US-ASCII',因此如果有任何非 ASCII 字符,您将得到一个明确的错误,而不是错误的输出。)
【讨论】:
以上是关于将带有 CRLF 行终止符的 Little-endian UTF-16 Unicode 英文文本文件转换为 Ascii 编码的主要内容,如果未能解决你的问题,请参考以下文章
多平台 C++ 项目和 CMakeLists.txt 源中的行终止