有没有办法在C++中检查字符串是否包含Unicode字符?
我有一个字符串,需要验证它是否包含Unicode(UTF-8或UTF-16)字符。如果是,我需要将它们转换为ASCII。我对转换逻辑有一些想法,但需要帮助检测字符串中的Unicode字符。
有没有办法在C++中检查字符串是否包含Unicode字符?
我有一个字符串,需要验证它是否包含Unicode(UTF-8或UTF-16)字符。如果是,我需要将它们转换为ASCII。我对转换逻辑有一些想法,但需要帮助检测字符串中的Unicode字符。
如果文件以三字节序列0xEF、0xBB、0xBF开头,那么它很可能是UTF-8编码。在这种情况下,请删除这三个字节,并将剩余部分视为UTF-8进行处理(见下文)。
如果文件以两个字节序列0xFE、0xFF开头,则可能是UTF16BE编码。请删除这两个字节,并将剩余部分视为UTF16BE进行处理(见下文)。
如果文件以两个字节序列0xFF、0xFE开头,则可能是UTF16LE编码。请删除这两个字节,并将剩余部分视为UTF16LE进行处理(见下文)。
如果文件中每隔一个字节(从第一个字节开始)大多数都为0,则该文件很可能是UTF16BE编码。(“大多数”数量不定,取决于数据来源,甚至只有几个也足够了)。请将其作为UTF16BE进行处理(见下文)。
如果文件中每隔一个字节(从第二个字节开始)大多数都为0,则很可能是UTF16LE编码(在Windows世界中非常常见)。
否则,这将是任何人的猜测,但将其视为UTF-8进行处理(不删除任何字节)可能是可以接受的。
至于如何处理文件:
对于UTF-8编码,只需检查所有剩余字节是否在范围[0,128)内。如果不在,则该文件无法转换为ASCII;如果是,则该文件既是ASCII,也是UTF-8。对于大多数单字节编码,例如所有ISO-8859编码(仍然广泛使用),这也是有效的。
对于UTF16BE编码,每隔一个字节(从第一个字节开始)应为0,而其他剩余字节应在范围[0,128)内。如果不在,则该文件无法转换为ASCII;如果是,则取每隔一个字节(从第二个字节开始)。
对于UTF16LE编码,每隔一个字节(从第二个字节开始)应为0,而其他剩余字节应在范围[0,128)内。如果不在,则该文件无法转换为ASCII;如果是,则取每隔一个字节(从第一个字节开始)。
在所有情况下,在第一步删除任何字节后开始此处理过程。
最后,您没有说明您正在尝试做什么。有编码约定可以在纯ASCII中表示所有Unicode字符;如果您生成的ASCII将由期望其中一种约定的代码处理,则必须处理完整的Unicode(包括UTF-16中的代理对)并将Unicode转换为目标程序所期望的任何编码。例如,C++期望通用字符名称;例如,é
的表示形式将是\u00E9
。这意味着您还必须将\
转换为\\
。(据我所知,这种约定仅适用于像C、C++和Java这样的编程语言。)
无法一概而论。
字符串只是字符的序列(可以是任意大小)。与这种序列密不可分的编码将文本含义附加到字符串上。
在Windows中使用的编码是UTF-16,它允许您进行尝试。它提供了API函数IsTextUnicode
,可以帮助您。但请注意,不能保证它会起作用。
ï«¿
,不太可能是文件的开头。 - James Kanzeï«¿
;在这种情况下,我的 "不太可能" 是一种轻描淡写的说法;我想不到这种情况下它会以这种方式开始。 - James Kanze