0

C++ 标准库中的大多数文本都提到 wstring 等同于 string,除了在 wchar_t 上参数化而不是 char,然后继续仅演示 string。

嗯,有时,有一些特定的怪癖,这里有一个:我似乎无法从一个 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?

谢谢

4

3 回答 3

9

在大多数 Unix(Mac OS X 也是)下,whar_t表示 UTF-32 单代码点,而不是像 windows 那样的 16 位 utf-16 点。

所以你需要:

  1. 任何一个:

    ws.assing(arr,arr + length_of_string);
    

    这将使用 arr 作为迭代器并将每个短 int 复制到 wchar_t。但这仅在您的字符位于 BMP 或表示 UCS-2(16 位传统编码)时才有效。

  2. 或者,正确使用 utf-16:将 utf-16 转换为 utf-32——您需要找到代理对并将它们合并到单个代码点。

于 2009-08-27T11:58:25.243 回答
3

去做就对了。您没有在代码中,将一组无符号短裤分配给 wstring,并使用强制转换来关闭编译器。wchar_t != 无符号短。您当然不能假设它们具有相同的大小。

于 2009-08-27T12:36:38.623 回答
0

我认为你的代码可以工作,只是通过检查。但是你总是可以解决这个问题:

ws.assign(static_cast<const wchar_t*>(arr), wcslen(arr));
于 2009-08-27T12:04:34.433 回答