Как получить размер байта байтовой строки

Как я получаю размер байта строки многобайтовых символов в Визуальном C? Существует ли функция, или я должен считать символы сам?

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

Решение:

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

Править:
Я говорил о завершенных пустым указателем строках только.

8
задан flacs 29 July 2010 в 00:28
поделиться

2 ответа

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

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

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

3
ответ дан 5 December 2019 в 13:59
поделиться

Давайте посмотрим, смогу ли я прояснить это:

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

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

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

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

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

... и множество функций для решения этой проблемы. (Примерно так работает std::string)

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

Теперь, "широкие" или "юникодовые" строки в мире MS относятся к строкам UTF-16. Они имеют схожие проблемы, поскольку количество байтов != количеству символов. (Также: количество байт / 2 != количество символов) Давайте посмотрим на thé еще раз:

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

Это "thé" в UTF-16, сохраненное в little endian (что является типичным для вашего рабочего стола). Обратите внимание на все байты 00 - они сбивают strlen. Таким образом, мы вызываем wcslen, который рассматривает его как двухбайтовые shortы, а не одиночные байты.

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

9
ответ дан 5 December 2019 в 13:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: