(Закодировано) Обработка строк в C ++ - вопросы / лучшие практики? - PullRequest
3 голосов
/ 11 января 2009

Каковы лучшие практики для обработки строк в C ++? Мне особенно интересно, как обращаться со следующими случаями:

  • Ввод / вывод файлов текста и файлов XML, которые могут быть записаны в разных кодировках. Каков рекомендуемый способ справиться с этим и как получить значения? Я предполагаю, что узел XML может содержать текст UTF-16, и тогда мне придется как-то с ним работать.

  • Как обращаться с char* строками. В конце концов, это может быть без знака или нет, и мне интересно, как определить, какую кодировку они используют (ANSI?) И как преобразовать в UTF-8? Есть ли рекомендуемые материалы по этому вопросу, где документированы основные гарантии C / C ++ относительно строк?

  • Строковые алгоритмы для строк UTF-8 и т. Д. - вычисление длины, анализ и т. Д. Как это лучше всего сделать?

  • Какой тип символов действительно переносимый? Я узнал, что wchar_t может быть любым размером от 8 до 32 бит, что делает его бесполезным, если я хочу быть согласованным между платформами (особенно при перемещении данных между различными платформами - это кажется проблемой, как описано для пример в EASTL, посмотрите на элемент # 13 )

В настоящее время я использую std::string везде, с небольшой вспомогательной утилитой для преобразования в UTF-16 при вызове Unicode-API, но я уверен, что это не самый лучший способ. Использование чего-то вроде QString в Qt или класса ICU String кажется правильным, но мне интересно, есть ли более легкий подход (т. Е. Если мои строки char закодированы в ANSI, а подмножество ANSI, которое используется, равно UFT-8, тогда я могу легко обрабатывать данные как UTF-8 и предоставлять конвертеры из / в UTF-8, и я готов, поскольку я могу сохранить их в std::string, если нет проблем с этим подходом).

Ответы [ 2 ]

3 голосов
/ 12 января 2009

Для краткого ответа я бы просто порекомендовал использовать UTF-16 для простоты; Java / C # / Python 3.0 переключился на эту модель именно для простоты. Я всегда ожидал, что wchar_t будет иметь ширину 16 или 32 бита, и многие платформы поддерживают это; действительно, API, такие как wcrtomb (), не позволяют реализации поддерживать состояние сдвига для wchar_t *, но поскольку UTF-8 не нуждается ни в одном, он может использоваться, в то время как другие кодировки исключены.

Затем я отвечаю на вопрос о XML.

Ввод / вывод файлов текста и файлов XML, которые могут быть записаны в разных кодировках. Каков рекомендуемый способ справиться с этим и как получить значения? Я предполагаю, что узел XML может содержать текст UTF-16, и тогда мне придется как-то с ним работать.

Я не уверен, но я так не думаю. Смешивание двух кодировок в одном файле вызывает проблемы и повреждение данных. Кодирование файла в UTF-16 обычно является плохим выбором, так как большинство программ используют ASCII везде. Проблема заключается в том, что XML-файл может использовать любую отдельную кодировку, может быть, даже UTF-16, но в первоначальном объявлении кодировки также должен использоваться UTF-16 и даже теги. Проблема, которую я вижу с UTF-16, заключается в следующем: как надежно разобрать начальную декларацию? Ответ приходит в спецификации: § 4.3.3:

В отсутствие информации, предоставляемой внешним транспортным протоколом (например, HTTP или MIME), для объекта, включающего в себя объявление кодировки, представляется фатальной ошибкой представление процессору XML в кодировке, отличной от указанной в объявлении. или для объекта, который начинается ни с метки порядка байтов, ни с объявления кодирования, чтобы использовать кодировку, отличную от UTF-8. Обратите внимание, что, поскольку ASCII является подмножеством UTF-8, обычные объекты ASCII строго не нуждаются в объявлении кодировки.

При чтении этого обратите внимание, что файл XML также является сущностью, называемой сущностью документа; в общем, сущность является единицей хранения документа. Из всей спецификации я бы сказал, что для каждой сущности разрешено только одно объявление кодировки, и я бы преобразовал все сущности в UTF-16 при чтении их для упрощения обработки.

Webography:

1 голос
/ 12 января 2009

Строковые алгоритмы для строк UTF-8 и т. Д. - вычисление длины, анализ и т. Д. Как это лучше всего сделать?

mbrlen дает длину строки C. Я не думаю, что std :: string можно использовать для многобайтовых строк, вы должны использовать wstring для широких.

В общем, вы должны придерживаться UTF-16 внутри вашей программы и использовать UTF-8 только при вводе / выводе (я не знаю других вариантов, но они, безусловно, более сложны и подвержены ошибкам).

Как обращаться с символьными * строками. В конце концов, это может быть без знака или нет, и мне интересно, как определить, какую кодировку они используют (ANSI?) И как преобразовать в UTF-8? Есть ли рекомендуемые материалы по этому вопросу, где документированы основные гарантии C / C ++ относительно строк?

По сути, вы можете использовать любую кодировку, и вам случится использовать собственную кодировку системы, в которой вы работаете, при условии, что это 8-битная кодировка. C был рожден для ASCII, и обработка языка была запоздалой мыслью. В течение многих лет каждая система понимала в основном одну встроенную кодировку, скажем, ISO-8859-x, и файлы из другой кодировки могли даже не быть представленными.

Поскольку для строк UTF-8 один байт не всегда является одним символом, я предполагаю , что наиболее безопасным вариантом является использование для них многобайтовой строки. Руководства C, которые я использовал, описывали многобайтовую строку в абстрактной форме, без подробностей по этим вопросам (в частности, по используемой кодировке). Для C, смотрите такие функции, как mbrlen и mbrtowc. В моей системе Linux отмечено, что их поведение зависит от LC_CTYPE, и это, вероятно, означает, что это собственный тип многобайтовых строк. Из документации можно сделать вывод, что их API поддерживает также кодировки, в которых вы можете переходить с однобайтового на двухбайтовый и обратно.

Как обращаться с символьными * строками. В конце концов, это может быть без знака или без

Если вы полагаетесь на подпись char, вы делаете это неправильно. Подпись символов имеет значение только в том случае, если вы используете символ в качестве числового типа, и тогда вы всегда должны использовать либо без знака, либо со знаком символы; на самом деле, вы должны сделать вид, что обычный символ не является ни беззнаковым, ни со знаком, и что выражение типа a > 0 (если a является символом) имеет неопределенную семантику. Но для чего это все-таки полезно?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...