2016-06-01 8 views
0

Приложение Windows C++. У нас есть строка, которая содержит только символы ASCII: std::wstring(L"abcdeABCDE ... any other ASCII symbol"). Обратите внимание, что это std::wstring, который использует wchar_t.байтовое представление символов ASCII в std :: wstring с разными локалями

Вопрос: представление байтов этой строки зависит от настроек локализации или чего-то еще? Могу ли я предположить, что если я получаю такую ​​строку (например, из WindowsAPI), когда приложение работает, ее байты будут такими же, как на моем ПК?

+1

Вы используете строку Unicode, закодированный в UTF-16 во время выполнения. Это не зависит от языка, это Unicode. Все, что вы получаете от winapi, будет Unicode, а также с UNICODE #defined. Строковые литералы с символами, отличными от ASCII, зависят от вашего текстового редактора, сохраняющего файл .cpp в кодировке Unicode, которую компилятор может распознать, используя utf-8 с спецификацией, чтобы он не превращался в mojibake, когда ваш исходный код перемещается в другом месте. –

+0

@ HansPassant Спасибо за отзыв! Но мне нужен только небольшой диапазон символов ASCII (a-zA-Z, пробел, точка). У меня нет большого опыта работы с файлами Windows/Unicode, поэтому я попросил его быть уверенным на 100%. Кажется, я прав, и представление этих символов ни на что не зависит. –

+0

Это может помочь забыть о ASCII. В Win32 API вы используете Unicode/UTF-16. Почти никто не будет использовать весь набор символов Unicode, поэтому почти каждая программа будет использовать подмножество Unicode.Не имеет значения, является ли подмножество, которое вы используете, также подмножеством набора символов, который вы не используете. –

ответ

1

В целом для символов (не escape-последовательность) wchar_t и wstring должны использовать те же коды, что и ASCII (только для двух байтов). Но я не уверен в кодах менее 32 и, конечно, коды, превышающие 128 бит, могут иметь разное значение (как в ASCII) в момент вывода, поэтому, чтобы избежать проблемы с выходом, задайте конкретную локаль явно, например:

locale("en_US.UTF-8") 

для стандартного вывода

wcout.imbue(locale("en_US.UTF-8")); 

UPDATE:

Я нашел еще одно предложение о добавлении

std::ios_base::sync_with_stdio(false); 

перед установкой локализации с imbue

см подробности о How can I use std::imbue to set the locale for std::wcout?

+0

Спасибо !!! Мне нужен только узкий диапазон символов ASCII - символы a-zA-Z и несколько специальных символов, таких как пространство, точка и т. Д. Теперь я более уверен)) –

1

байт представление символьной строки не зависит от окружающей среды. Он жестко привязан к двоичным данным из редактора. Однако способ интерпретации двоичных данных зависит от текущей кодовой страницы, поэтому вы можете получить разные результаты при преобразовании во время выполнения в широкую строку (в отличие от определения строки с использованием ведущего L, что означает, что широкие символы будет установлен во время компиляции.)

Чтобы быть в безопасности, используйте setlocale(), чтобы гарантировать кодирование, используемое для преобразования. Тогда вам не нужно беспокоиться об окружающей среде.

Это может помочь: «По определению набор символов ASCII является подмножеством всех наборов многобайтовых символов. Во многих многобайтовых наборах символов каждый символ в диапазоне 0x00 - 0x7F идентичен символу с одинаковым значением в наборе символов ASCII. Например, в символьных строках ASCII и MBCS 1-байтовый символ NULL ('\ 0') имеет значение 0x00 и указывает завершающий нулевой символ. "

От: Visual Studio Character Sets 'Not set' vs 'Multi byte character set'