Найти длину в символах std :: wstring - PullRequest
0 голосов
/ 21 августа 2011

Я работаю с переменными std :: wstring (язык C ++) и пытаюсь определить длину (в символах) строки.

Функции .length & .size () дают результаты, которые не имеют длину в символах (я думаю, они говорят мне, сколько существует широких символов?).

Так есть ли способ определить длину в символах строки?

Ответы [ 4 ]

6 голосов
/ 21 августа 2011

Что вы подразумеваете под "персонажами"?

std::basic_string - это просто контейнер для ряда значений, который мы считаем строкой. Неважно, в чем кодировка значений; все, что он делает, это хранит и управляет упорядоченной последовательностью значений. Поэтому функции size и length определяют, сколько значений он хранит.

Если ваш std::wstring содержит строку, которая представляет, скажем, действительную строку в кодировке UTF-16, std::wstring не имеет значения. Unicode-кодировки - это просто способы кодирования кодовых точек. UTF-16 использует 16-битные кодовые единицы для кодирования своих кодовых точек, которые могут включать суррогатные пары 16-битных значений, которые соответствуют одной кодовой точке Unicode.

Однако код Unicode не является «символом» в некоторых определениях этого термина. Например, существуют комбинированные кодовые точки, где несколько кодовых точек объединяются для формирования графемы. Есть невидимые кодовые точки (контрольные коды и т. П.).

Если вы хотите знать, сколько кодовых точек в std::wstring, вам придется пройтись по этой строке с помощью функции, которая может обрабатывать данные UTF-16. Если вы хотите узнать, сколько графем (логических глифов) содержится в строке, вам нужно будет пройтись по нему с гораздо более сложным алгоритмом.

5 голосов
/ 21 августа 2011

Для этого вы должны использовать базу данных Unicode. Вы должны использовать ICU (, как это сделать в ICU ) или какую-либо другую библиотеку Unicode. Boost.Locale уже одобрен для повышения и скоро будет доступен, он прекрасно оборачивает некоторые функции ICU.

Однако я сомневаюсь, что вам действительно нужно это сделать. См. определения графемы, символа, кодовой точки, кодового блока . Возможно, вы имеете в виду кодовые точки, но почти наверняка это не очень полезно.

2 голосов
/ 21 августа 2011

В зависимости от того, откуда взялась ваша строка, у вас может не быть какого-либо контроля над тем, что это означает , т.е. как она закодирована. Чтобы превратить вашу строку во что-то определенную семантику, вам может потребоваться выполнить следующие шаги:

  1. Чтение байтовой строки из среды через argv или getenv. Это байтовая строка с кодировкой, зависящей от платформы и локали.

  2. Превратите строку байтов во внутреннюю строку фиксированной ширины (есть предостережения) с помощью mbstowcs(). Вы все еще не знаете кодировку результата! Все, что вы знаете, это то, что каждый широкий символ достаточно велик, чтобы содержать любое из «значений символов платформы», что бы это ни значило. (В Windows это означает что-то сломано ).

  3. Получите последовательность кодовых точек Unicode (то есть точных данных, которыми вы можете манипулировать с помощью кодовой точки), используя ICU или iconv() для перевода WCHAR в UCS-4 / UTF-32. Теперь вы знаете, с чем имеете дело!

Если вы читаете данные из файла с документированной кодировкой или из сети, вместо этого вы должны конвертировать из документированной кодировки файлов в UCS-4.

Как только вы получили последовательность кодовых точек, поддержка низкоуровневого языка для обработки текста заканчивается. Последовательность кодовых точек - лучшее, что вы можете получить на двоичном уровне для представления текста. Любые текстовые манипуляции и обработка на более высоком уровне являются сложными и тонкими и глубоко зависят от правильного определения «текста», поэтому лучше оставить их в специальной библиотеке Unicode (такой как ICU). На уровне языка программирования «символы» - это кодовые точки, но в любом серьезном приложении это, вероятно, не то, что вам нужно, и вы хотите знать о графемах и нормализации и сотне других мелочей.

0 голосов
/ 21 августа 2011

Вы ищете wcslen?

#include <wchar.h>
size_t wcslen(const wchar_t *s);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...