2014-12-17 4 views
1

Есть ли способ, чтобы проверить, содержит ли строка символов Юникода в C++Есть ли способ, чтобы проверить, содержит ли строка символов Юникода в C++

У меня есть строка, и мне нужно, чтобы проверить, содержит ли это Unicode (UTF -8 или UTF-16). Если это нужно, мне нужно преобразовать их в ASCII. У меня есть некоторое представление о логике преобразования., Но вам нужна помощь в обнаружении символов Юникода в строке

+2

Вы можете использовать регулярное выражение – deW1

+3

Я не хочу испортить здесь удовольствие, но это абсолютно невозможно * надежно * определить кодировку данных. Каждое «решение» основано на угадывании (в процентах от некоторых байтов и символов на некоторых языках, возможно даже распознавании слов и т. Д.). – deviantfan

+0

Откуда эта строка? если это из файла, то вежливая вещь заключается в том, что файл укажет, что он является юникодом по наличию [BOM] (http://en.wikipedia.org/wiki/Byte_order_mark) – EdChum

ответ

2

Вы не можете сказать в полной общности.

Строка - это всего лишь последовательность символов (которая может быть любого размера). Кодировка ; неразрывно связанные с такой последовательностью; придает текстуру значение текстуре.

В Windows используется кодировка UTF-16, которая позволяет вам иметь пунт. Он предоставляет функцию API IsTextUnicode, которая может справка. Но обратите внимание, что нет никакой гарантии, что он будет работать.

+0

(Замечание во избежание путаницы: Windows использует UTF16 во многих местах, но это не означает, что каждая программа и файл в Windows - UTF16) – deviantfan

2

Существует не 100% гарантированное решение. Я бы начать с прочтения первых 100 или так байт, и попытаться определить кодировку:

  • Если файл начинается с последовательности три байта 0xEF, 0xBB, 0xbf, это вероятно, UTF-8. В этом случае отбросьте эти три и обработайте остальные как UTF-8, ниже.

  • Если файл начинается с двух байтовой последовательности 0xFE, 0xFF, это, вероятно, UTF16BE. Отбросьте эти два, и обработайте остальные как UTF16BE, ниже.

  • Если файл начинается с двух байтовых последовательностей 0xFF, 0xFE, это , вероятно, UTF16LE. Бросьте эти два, и обработайте остальные как UTF16LE, ниже.

  • Если каждый другой байт, начиная с первого, в основном 0, то файл , вероятно, UTF16BE. (В основном зависит от того, в зависимости от источника данных , может быть даже больше пары.) Процесс как UTF16BE, ниже.

  • Если каждый другой байт, начиная со второго, в основном 0, это , вероятно, UTF16LE (очень часто в мире Windows).

  • В противном случае это все догадывается, но обработка его, как если бы она была UTF-8 (без потери каких-либо байтов), вероятно, приемлема.

А как обработать файл:

  • Для UTF-8, просто убедитесь, что все остальные байты находятся в диапазоне [0128). Если это не так, файл не может быть преобразован в ASCII. Если они , то файл : ASCII (а также UTF-8). Это также относится к для большинства однобайтовых кодировок, например. все кодировки ISO-8859 (которые по-прежнему широко распространены).

  • Для UTF16BE каждый другой байт, начиная с первого, должен быть 0 и оставшихся байтов в диапазоне [0,128). Если это не так, файл не может быть преобразован в ASCII . Если они есть, возьмите каждый другой байт, начиная с второй.

  • Для UTF16LE каждый другой байт, начиная со второго, должен быть 0, и оставшиеся байты в диапазоне [0,128). Если это не так, файл не может быть преобразован в ASCII. Если да, возьмите каждый байт, , начиная с первого.

Во всех случаях эта обработка начинается после падения любые байты из первого шага.

Наконец, вы не говорите, что вы пытаетесь сделать. Существуют кодировки , которые позволяют представлять все символы Unicode в чистом виде ASCII; если созданный вами ASCII будет обработан кодом, ожидающим один из этих соглашений, вам придется обработать полный Юникод (включая суррогатные пары в UTF-16) и преобразовать Юникод в , какую кодировку ожидает целевая программа , C++, например, ожидает универсальных имен символов; представление для é, для пример, будет \u00E9. Это означает, что вам также необходимо будет преобразовать \ в \\. (Насколько я знаю, это соглашение применимо только к программированию языков, таких как C, C++ и Java.)

Смежные вопросы