C++ 微软';lstrcmpi和Unicode字符的s实现

C++ 微软';lstrcmpi和Unicode字符的s实现,c++,windows,winapi,unicode,C++,Windows,Winapi,Unicode,我想知道我看到的是一个bug,还是微软功能的一些公认行为 我可以用代码来说明: WCHAR buff1[] = L"abc "; WCHAR buff2[] = L"abc "; buff1[3] = 0xFFFF; buff2[3] = 0x0; int res = lstrcmpi(buff1, buff2); //res is 0 or equality! 编辑:添加以下评论: UnicodeFFFF字符在Unicode规范中是非字符,因此在字符串比较过程中可能会忽略它。这会导致两个字符

我想知道我看到的是一个bug,还是微软功能的一些公认行为

我可以用代码来说明:

WCHAR buff1[] = L"abc ";
WCHAR buff2[] = L"abc ";
buff1[3] = 0xFFFF;
buff2[3] = 0x0;
int res = lstrcmpi(buff1, buff2);
//res is 0 or equality!
编辑:添加以下评论:


Unicode
FFFF
字符在Unicode规范中是非字符,因此在字符串比较过程中可能会忽略它。这会导致两个字符串相等。

Unicode
FFFF
字符在Unicode规范中是非字符,因此在字符串比较过程中可能会忽略它。这将导致两个字符串相等。

lstrcmpi
调用
CompareString
与当前区域设置()并返回“语言上合适的结果”

发件人:

。。。现在,如果函数名为lstrcoll和lstrcolli,那么该函数可能不会经常被误用

:

请记住,当检查相等性时,特别是在涉及操作系统语义的注册表值之类的项目上,最好的答案是CompareStringOrdinal,使用RtlCompareUnicodeString或更好的RtlEqualUnicodeString,或者如果您绝对必须使用wcsicmp(意识到其中有一个字符可能是错误的)对于必须运行Vista之前版本的任何内容

:

因为如果您出于适当的原因调用lstrcmpi(即,您希望获得有语言意义的结果,比如在用户界面中对列表进行排序),但希望行为不会随不同的语言环境而变化,那么使用语言环境_不变量进行比较是一个很好的答案

但是,如果您想要其他任何东西,包括前面提到的所有非语言目的,那么CompareStringOrdinal或RTLCompareInocDestring是一个更好的选择


它处理非字符的方式实际上已经改变。

lstrcmpi
调用
CompareString
与当前区域设置()并返回“语言上合适的结果”

发件人:

。。。现在,如果函数名为lstrcoll和lstrcolli,那么该函数可能不会经常被误用

:

请记住,当检查相等性时,特别是在涉及操作系统语义的注册表值之类的项目上,最好的答案是CompareStringOrdinal,使用RtlCompareUnicodeString或更好的RtlEqualUnicodeString,或者如果您绝对必须使用wcsicmp(意识到其中有一个字符可能是错误的)对于必须运行Vista之前版本的任何内容

:

因为如果您出于适当的原因调用lstrcmpi(即,您希望获得有语言意义的结果,比如在用户界面中对列表进行排序),但希望行为不会随不同的语言环境而变化,那么使用语言环境_不变量进行比较是一个很好的答案

但是,如果您想要其他任何东西,包括前面提到的所有非语言目的,那么CompareStringOrdinal或RTLCompareInocDestring是一个更好的选择


它处理非字符的方式实际上已经改变了。

@Jonathan,这些文字只被用作数组的初始值设定项,而不是写入数组。对U+FFFF进行了一些讨论,得出了一个普遍的想法,即除非内部逻辑将其用作哨兵之类的东西,否则它通常不应该出现在字符串中。也许lstrcmpi有一些特殊情况,但你不应该绊倒它,因为你根本不应该传递它。@TheUndeadFish:正如我在下面对答案的评论中所说,它不仅仅是
FFFF
。我在
FFFE
中看到了同样的情况。。。。也许其他人。总而言之,我认为这是低级字符串比较API的一种危险行为。听起来你把它与
wcscmp
和/或
\wcsicmp
混淆了,后者可能会以你想要的方式运行?@c0000fd取决于你的期望和他们的目标。例如,您是否希望L“é”等于L“e\u0301”(带有comibing口音的e)?由于lstrcmpi确实将它们称为相等,我认为它的目标是根据人类所看到的而不是逐字节工作。因此,我假设像U+FFFF和U+FFFE这样的不可用/不可打印字符被视为无关字符。不管那是否危险。。。这不是我该做的。但也许它不适合您的用例?@Jonathan,这些文字只是用作数组的初始值设定项,他没有在数组中写入。对U+FFFF进行了一些讨论,得出了一个普遍的想法,即除非内部逻辑将其用作哨兵之类的东西,否则它通常不应该出现在字符串中。也许lstrcmpi有一些特殊情况,但你不应该绊倒它,因为你根本不应该传递它。@TheUndeadFish:正如我在下面对答案的评论中所说,它不仅仅是
FFFF
。我在
FFFE
中看到了同样的情况。。。。也许其他人。总而言之,我认为这是低级字符串比较API的一种危险行为。听起来你把它与
wcscmp
和/或
\wcsicmp
混淆了,后者可能会以你想要的方式运行?@c0000fd取决于你的期望和他们的目标。例如,您是否希望L“é”等于L“e\u0301”(带有comibing口音的e)?由于lstrcmpi确实将它们称为相等,我认为它的目标是根据人类所看到的而不是逐字节工作。因此,我假设像U+FFFF和U+FFFE这样的不可用/不可打印字符被视为无关字符。不管那是否危险。。。这不是我该做的。但也许它不适合您的用例?是的,这是一个有趣的行为。而且不仅仅是
lstrcmpi
。我在
lstrcmp
CompareString
(区分大小写和不区分大小写)中看到了相同的行为,也在其他字符中看到了相同的行为,例如
FFFE
。只有C的
me能捕捉到它