Количество байтов CString в C++

У меня есть строка Unicode, хранящаяся в CString, и мне нужно знать число байтов, которое эта строка занимает в кодировке UTF-8. Я знаю, что у CString есть метод getLength(), но он возвращает количество символов, а не байтов.

Я пытался (помимо прочего) преобразовать в массив символов, но я получаю (логически, я думаю) только массив wchar_t, так что это не решает мою проблему.

Чтобы было ясно о моей цели. Для ввода скажем "aaa" Я хочу "3" в качестве вывода (поскольку "a" занимает один байт в UTF-8). Но для ввода «āaa» я бы хотел видеть вывод «4» (поскольку ā — двухбайтовый символ).

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

У меня очень мало опыта программирования под Windows, поэтому, возможно, я упустил какую-то важную информацию. Если вы чувствуете, как это, пожалуйста, дайте мне знать, я добавлю любую информацию, которую вы запрашиваете.


person Kejml    schedule 20.04.2014    source источник


Ответы (1)


Поскольку ваша CString содержит ряд wchar_t, вы можете просто использовать WideCharToMultiByte с выходной кодировкой CP_UTF8. Функция вернет количество байтов, записанных в выходной буфер, или длину строки в кодировке UTF-8.

LPWSTR instr;
char outstr[MAX_OUTSTR_SIZE];
int utf8_len = WideCharToMultiByte(CP_UTF8, 0, instr, -1, outstr, MAX_OUTSTR_SIZE, NULL, NULL);

Если вам не нужна выходная строка, вы можете просто установить размер выходного буфера равным 0.

  • cbMultiByte

    Размер буфера в байтах, указанный параметром lpMultiByteStr. Если этот параметр равен 0, функция возвращает требуемый размер буфера для lpMultiByteStr и не использует сам выходной параметр.

В этом случае функция вернет количество байтов в UTF-8, ничего не выводя.

int utf8_len = WideCharToMultiByte(CP_UTF8, 0, instr, -1, NULL, 0, NULL, NULL);

Если ваша CString действительно CStringA, т. е. _UNICODE не определена, вам нужно использовать Multi­Byte­To­Wide­Char для преобразования строки в UTF-16, а затем преобразовать из UTF-16 в UTF-8 с Wide­Char­To­Multi­byte. См. Как преобразовать строку ANSI напрямую в UTF-8? Но новый код ни в коем случае нельзя компилировать без поддержки Unicode

person phuclv    schedule 20.04.2014
comment
Имейте в виду, что если вы установите для параметра cchWideChar значение -1, WideCharToMultiByte() принимает во внимание нулевой терминатор, и результирующая длина включает нулевой терминатор. Если вы этого не хотите, вы должны установить cchWideChar на фактическую длину данных, передаваемых в параметр lpWideCharStr. - person Remy Lebeau; 24.04.2014