std::string
не определяет конкретную кодировку. Таким образом, вы можете хранить любую последовательность байтов в нем. Есть тонкости, о которых нужно знать:
.c_str()
вернет буфер с нулевым символом в конце. Если ваш набор символов допускает нулевые байты, не передавайте эту строку функциям, которые принимают параметр const char*
без длины, иначе ваши данные будут усечены.
- A
char
представляет не символ, а ** байт . ИМХО, это самая проблемная номенклатура в истории вычислений. Обратите внимание, что wchar_t
также обязательно должен содержать полный символ, в зависимости от нормализации UTF-16.
.size()
и .length()
вернут число байтов , а не количество символов.
[править] Предупреждения о ярлыках case
связаны с проблемой (2). Вы используете оператор switch
с многобайтовыми символами типа char
, который не может содержать более одного байта. [/ edit]
Таким образом, вы можете использовать std::string
в своем заявлении при условии соблюдения этих трех правил. Существуют тонкости, связанные с STL, включая std::find()
, которые являются следствием этого. Вам нужно использовать несколько более умных алгоритмов сопоставления строк для правильной поддержки Unicode из-за форм нормализации.
Однако при написании приложений на любом языке, в котором используются символы, не входящие в ASCII (если вы параноик, учтите это за пределами [0, 128)
), вам необходимо помнить о кодировках в различных источниках текстовых данных.
- Кодировка source-file может быть не указана и может быть изменена с использованием параметров компилятора. Любой строковый литерал будет подчинен этому правилу. Наверное, поэтому вы получаете предупреждения.
- Вы получите различные кодировки символов из внешних источников (файлы, пользовательский ввод и т. Д.). Когда этот источник указывает кодировку или вы можете получить ее из какого-либо внешнего источника (то есть, запрашивая пользователя, который импортирует данные), тогда это проще. Многие (более новые) интернет-протоколы налагают ASCII или UTF-8, если не указано иное.
Эти две проблемы не рассматриваются каким-либо конкретным строковым классом. Вам просто нужно преобразовать любой внешний источник в вашу внутреннюю кодировку. Я предлагаю UTF-8 все время, но особенно в Linux из-за встроенной поддержки. Я настоятельно рекомендую помещать строковые литералы в файл сообщений, чтобы забыть о проблеме (1) и иметь дело только с проблемой (2).
Я не предлагаю использовать std::wstring
в Linux, потому что 100% нативных API используют сигнатуры функций с const char*
и имеют поддержку direct для UTF-8. Если вы используете какой-либо строковый класс, основанный на wchar_t
, вам нужно будет конвертировать в / из std::wstring
без остановок и в конечном итоге получить что-то не так, в дополнение к замедлению (*)
Если бы вы писали приложение для Windows, я бы предложил прямо противоположное, потому что все нативные API используют const wchar_t*
подписи. Версии ANSI таких функций выполняют внутреннее преобразование в / из const wchar_t*
.
Некоторые «переносимые» библиотеки / языки используют разные представления в зависимости от платформы. Они используют UTF-8 с char
в Linux и UTF-16 с wchar_t
в Windows. Я помню, как читал об этом приеме в ссылочной реализации Python, но статья была довольно старой. Я не уверен, правда ли это больше.