Как я получаю размер байта строки многобайтовых символов в Визуальном C? Существует ли функция, или я должен считать символы сам?
Или, более общий, как я получаю правильный размер байта строки TCHAR?
Решение:
_tcslen(_T("TCHAR string")) * sizeof(TCHAR)
Править:
Я говорил о завершенных пустым указателем строках только.
Согласно MSDN, _tcslen
соответствует strlen
, когда определено _MBCS
. strlen
вернет количество байт в строке. Если вы используете _tcsclen
, это соответствует _mbslen
, который возвращает количество многобайтовых символов.
Также, многобайтовые строки не содержат (AFAIK) встроенных нулей, нет.
Я бы поставил под сомнение использование многобайтовой кодировки в первую очередь, хотя... если вы не поддерживаете устаревшее приложение, нет причин выбирать многобайтовую кодировку вместо Юникода.
Давайте посмотрим, смогу ли я прояснить это:
"Многобайтовая символьная строка" - это расплывчатый термин, но в мире 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.