Функция mbtowcs не обрабатывает кодировку UTF-8, нет локали, которую вы можете установить для перевода UTF-8 в wchar_t. Поэтому я буду использовать примеры для Windows, но общая идея одинакова для большинства ОС.
В мире многобайтовых наборов символов не может быть одного значения для заданного восьмеричного значения и не может быть одного восьмеричного значения для любого заданного символа. Что означает конкретное восьмеричное значение и как представлен символ (или даже если он может быть представлен), определяется язык.
Когда mbstowcs возвращает ошибку, это в основном говорит вам, что нет расширенного символа, эквивалентного переданному ему многобайтовому символу. Это может означать, что символ UNICODE отсутствует (маловероятно, но не невозможно), или это может означать, что языковой стандарт не определяет символ для данного восьмеричного значения (или последовательности восьмеричных значений в случае многобайтовых символов).
Если вы явно не задали свой язык (позвонив setlocale), то вы получаете локаль в зависимости от конфигурации вашей системы. Чтобы получить текущую локаль, вы можете вызвать _get_current_locale. Как только вы узнаете свою локаль, вы можете выяснить, какой символ (если есть) представляет конкретное восьмеричное значение, а затем вы можете выяснить, каким будет эквивалент UNICODE (если есть).
Один из способов определить проблемный символ — изменить длину, передаваемую в mbstowcs, до тех пор, пока не будет найден единственный символ, вызывающий ошибку. Подход грубой силы может заключаться в том, чтобы начать с length=1 и увеличивать его до тех пор, пока mbstowcs не вернет -1.
Обновление от 25 июля
Из обсуждения комментариев мы обнаружили, что входная строка (скорее всего) закодирована как UTF-8. Хотя первоначальный ответ правильный (насколько это возможно), он не заходит достаточно далеко. В Windows вы не можете создать локаль, которая будет обрабатывать символы, закодированные в UTF-8.
Столкнувшись с UTF-8, вместо вызова mbtowcs мы можем вызвать MultiByteToWideChar с использованием кодовой страницы CP_UTF8, но этот код будет работать только в Windows...
BYTE bytes [] = {0xD7,0x99,0xD7,0x95,0xD7,0x97,0xD7,0x90,0xD7,0x99,0x20,0xD7,0x95,0xD7,0x9B,0xD7,0x98,0xD7,0xA8, 0x00};
int result;
// get length of converted string in characters
result = MultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, (char *)bytes,
sizeof (bytes), NULL, 0);
wchar_t * name = new wchar_t [result];
// convert string
result = MultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, (char *)bytes,
sizeof (bytes), name, result);
person
Frank Boyne
schedule
19.06.2011
mbstowcs
предназначен для взаимодействия с вашей средой выполнения. Если вы получаете строку путем десериализации источника с известной кодировкой, вы должны вместо этого использовать что-то вродеiconv
из вашей известной кодировки в WCHAR_T. - person Kerrek SB   schedule 01.07.2011