C ++标准库中的大多数文本都提到wstring等同于string,除了在wchar_t而不是char上进行参数化,然后继续演示字符串。
好吧,有时,有一些特定的怪癖,这里有一个:我似乎无法从以NULL结尾的16位字符数组中分配一个wstring。问题是赋值幸福地使用空字符和任何垃圾作为实际字符。这是一个非常小的减少:
typedef unsigned short PA_Unichar;
PA_Unichar arr[256];
fill(arr); // sets to 52 00 4b 00 44 00 61 00 74 00 61 00 00 00 7a 00 7a 00 7a 00
// now arr contains "RKData\0zzz" in its 10 first values
wstring ws;
ws.assign((const wchar_t *)arr);
int l = ws.length();
此时l不是预期的6(“RKData”中的字符数),而是更大。在我的测试运行中,它是29.为什么29?不知道。内存转储没有显示第29个字符的任何特定值。
所以问题:这是我的标准C ++库(Mac OS X Snow Leopard)中的错误,还是我的代码中的错误? 我怎么能把一个以空字符结尾的16位字符数组分配给一个wstring?
由于
答案 0 :(得分:9)
在大多数Unix(Mac OS X)下,whar_t
代表UTF-32单一代码点,而不是像windows一样16bit utf-16点。
所以你需要:
或者:
ws.assing(arr,arr + length_of_string);
那将使用arr作为迭代器并将每个short int复制到wchar_t。 但只有当你的角色存在于BMP或代表UCS-2时,这才会起作用 (16位传统编码)。
或者,正确使用utf-16:将utf-16转换为utf-32 - 您需要找到代理对并将它们合并到单个代码点。
答案 1 :(得分:3)
做吧。你没有在你的代码中,你为wstring分配了一个unsigned short数组,你使用了一个强制转换来关闭编译器。 wchar_t!= unsigned short。你当然不能假设它们的大小相同。
答案 2 :(得分:0)
我认为你的代码只会通过检查才能生效。但你总是可以解决这个问题:
ws.assign(static_cast<const wchar_t*>(arr), wcslen(arr));