Как получить размер байта многобайтовой строки - PullRequest
8 голосов
/ 29 июля 2010

Как получить размер байта многобайтовой символьной строки в Visual C?Есть ли функция или я должен сам посчитать символы?

Или, в более общем смысле, как получить правильный размер байта строки TCHAR?

Решение:

_tcslen(_T("TCHAR string")) * sizeof(TCHAR)

РЕДАКТИРОВАТЬ:
Я имел в виду только строки с нулевым символом в конце.

Ответы [ 2 ]

9 голосов
/ 29 июля 2010

Посмотрим, смогу ли я это прояснить:

«Многобайтовая символьная строка» - это неопределенный термин для начала, но в мире Microsoft он обычно означает «не ASCII и не UTF-16». Таким образом, вы можете использовать некоторую кодировку символов, которая может использовать 1 байт на символ, или 2 байта, или, возможно, больше. Как только вы это сделаете, количество символов в строке! = Количество байтов в строке.

Давайте возьмем UTF-8 в качестве примера, хотя он не используется на платформах MS. Символ é в памяти закодирован как «c3 a9» - таким образом, два байта, но 1 символ. Если у меня есть строка "thé", это:

text: t  h  é     \0
mem:  74 68 c3 a9 00

Это строка с нулевым символом в конце, так как она заканчивается нулем. Если бы мы хотели, чтобы в нашей строке были нулевые значения, нам нужно было бы сохранить размер другим способом, например:

struct my_string
{
    size_t length;
    char *data;
};

... и множество функций, помогающих справиться с этим. (Это примерно то, как работает std::string, довольно грубо.)

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

Теперь строки "wide" или "unicode" в мире MS относятся к строкам UTF-16. У них аналогичные проблемы в том, что количество байтов! = Количество символов. (Также: количество байтов / 2! = Количество символов) Давайте снова посмотрим на:

text:   t      h      é      \0
shorts: 0x0074 0x0068 0x00e9 0x0000
mem:    74 00  68 00  e9 00  00 00

Это «the» в UTF-16, хранящееся в порядке с прямым порядком байтов (это типичный рабочий стол). Обратите внимание на все 00 байтов - это отключение до конца. Таким образом, мы вызываем wcslen, который выглядит как 2-байтовые short с, а не как одиночные байты.

Наконец, у вас есть TCHAR s, что является одним из двух вышеупомянутых случаев, в зависимости от того, определено ли UNICODE. _tcslen будет соответствующей функцией (strlen или wcslen), а TCHAR будет char или wchar_t. TCHAR был создан для облегчения перехода на UTF-16 в мире Windows.

3 голосов
/ 29 июля 2010

Согласно MSDN , _tcslen соответствует strlen, когда определено _MBCS. strlen вернет число байтов в строке. Если вы используете _tcsclen, что соответствует _mbslen, который возвращает количество многобайтовых символов .

Кроме того, многобайтовые строки (AFAIK) не содержат встроенных нулей, нет.

Во-первых, я бы поставил под сомнение использование многобайтовой кодировки, хотя ... если вы не поддерживаете устаревшее приложение, нет причин выбирать многобайтовый код вместо Unicode.

...