C ++ wstring как назначить из массива wchar_t, заканчивающегося NULL - PullRequest
0 голосов
/ 27 августа 2009

Большинство текстов в стандартной библиотеке C ++ упоминают wstring как эквивалент строки, за исключением параметризации на wchar_t вместо char, а затем переходят к демонстрации только строки.

Ну, иногда есть некоторые специфические причуды, и вот один: мне кажется, я не могу назначить wstring из массива 16-битных символов с NULL-завершением. Проблема заключается в том, что в задании успешно используется нулевой символ, и любой мусор следует за реальными символами. Вот очень небольшое сокращение:

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?

Спасибо

Ответы [ 3 ]

9 голосов
/ 27 августа 2009

В большинстве Unix-систем (в том числе и в Mac OS X) whar_t представляет одну кодовую точку UTF-32, а не 16-битную точку utf-16, как в Windows.

Так что вам нужно:

  1. Или:

    ws.assing(arr,arr + length_of_string);
    

    Это будет использовать arr в качестве итератора и копировать каждое короткое int в wchar_t. Но это будет работать , только если ваши персонажи лежат в BMP или представляют UCS-2 (16-битное устаревшее кодирование).

  2. Или правильно работа с utf-16: преобразование utf-16 в utf-32 - вам нужно найти суррогатные пары и объединить их в одну кодовую точку.

3 голосов
/ 27 августа 2009

Просто сделай это. Вы не включили в свой код, вы присвоили массив неподписанных шорт wstring и использовали приведение, чтобы закрыть компилятор. wchar_t! = неподписанный короткий. Вы, конечно, не можете предположить, что они имеют одинаковый размер.

0 голосов
/ 27 августа 2009

Я думаю, твой код будет работать, просто проверяя. Но вы всегда можете обойти эту проблему:

ws.assign(static_cast<const wchar_t*>(arr), wcslen(arr));
...