假设我有一个接收字节数组的函数:
void fcn(byte* data)
{
...
}
有没有人知道fcn()确定数据是ANSI字符串还是Unicode字符串的可靠方法?
请注意,我故意不传递长度arg,我收到的只是指向数组的指针。一个长度arg将是一个很大的帮助,但我没有收到它,所以我必须没有。
本文提到了一个显然是这样做的OLE API,但当然他们没有告诉你WHICH api函数:http://support.microsoft.com/kb/138142
答案 0 :(得分:5)
首先,关于术语的一个词。没有ANSI字符串这样的东西;有ASCII字符串,表示字符编码。 ASCII由ANSI开发,但它们不可互换。
此外,没有Unicode字符串。有Unicode encodings,但这些只是Unicode本身的一部分。
我将假设“Unicode string”是指“UTF-8编码的代码点序列”。通过ANSI字符串,我假设您的意思是ASCII。
如果是这样,那么根据UTF-8编码的定义,每个ASCII字符串也是UTF-8字符串。 ASCII仅定义最大为0x7F的字符,所有UTF-8代码单元(字节)最高为0x7F,与ASCII相同。
因此,您关注的是其他128个可能的值。那太复杂了。
你问这个问题的唯一原因是你无法控制字符串输入的编码。因此,问题是ASCII和UTF-8 不是唯一可能的选择。
例如,拉丁语-1。有许多字符串在Latin-1中编码,它接受ASCII不使用的其他128个字节并为它们定义字符。这很糟糕,因为其他128个字节会与UTF-8的编码冲突。
还有code pages。许多字符串是针对特定代码页编码的;在Windows上尤其如此。解码它们需要知道您正在处理的代码页。
如果您处于某种的情况下,字符串是ASCII(7位,高位始终为0)或UTF-8,那么您可以轻松地进行判断。字符串是ASCII(因此也是UTF-8),或者一个或多个字节的高位设置为1.在这种情况下,您必须使用UTF-8 decoding logic。
除非您确实知道这些只是 的可能性,否则您将需要做更多的事情。您可以通过尝试通过UTF-8解码器运行数据来验证数据。如果它遇到无效的代码单元序列,那么你知道它不是UTF-8。问题是理论上可以创建一个技术上有效的UTF-8的Latin-1字符串。你有点搞砸了。基于代码页的字符串也是如此。
最终,如果您不知道字符串的编码是什么,则无法保证您可以正确显示它。这就是为什么知道你的字符串来自哪里以及它们意味着什么很重要的原因。