Ваш код wcstombs_s()
передает неверное значение параметру sizeInBytes
:
sizeInBytes
Размер в байтах mbstr
буфер.
Вы передаете в символ число japanese[i].name
, а не выделенный байт число japanese_char
. Они не имеют одинакового значения.
Кодовые точки Unicode кодируются в UTF-16 (какие строки wchar_t
кодируются как в Windows), используя 2 или 4 байта каждая, и в UTF-8, используя 1-4 байтакаждый, в зависимости от их стоимости. Кодовые точки Unicode в диапазоне U+0080..U+FFFF
занимают больше байтов в UTF-8, чем в UTF-16, поэтому возможно, что ваш буфер japanese_char
должен быть фактически выделен больше, чем ваши japanese[i].name
данные. Так же, как вы можете позвонить WideCharToMultiByte()
, чтобы определить необходимый размер буфера назначения, вы можете сделать то же самое с wcstombs_s()
.
size_t len = 0;
wcstombs_s(&len, NULL, 0, japanese[i].name, _TRUNCATE);
if (len == 0)
exit(EXIT_FAILURE);
char* japanese_char = malloc(len);
if (!japanese_char)
exit(EXIT_FAILURE);
wcstombs_s(&len, japanese_char, len, japanese[i].name, _TRUNCATE);
...
free(japanese_char);
Ваш WideCharToMultiByte()
код не имеет нулевого завершения dest
из-за того, что вы передали явный размер параметру cchWideChar
.
cchWideChar
Размер строки в символах, указанной в lpWideCharStr. В качестве альтернативы, этот параметр может быть установлен в -1, если строка заканчивается нулем. Если cchWideChar установлен в 0, функция завершается ошибкой.
Если этот параметр равен -1, функция обрабатывает всю входную строку, включая завершающий нулевой символ. Поэтому результирующая строка символов имеет завершающий нулевой символ, и длина, возвращаемая функцией, включает этот символ.
Если для этого параметра задано положительное целое число, функция обрабатывает точно указанное числоперсонажи. Если указанный размер не содержит завершающий нулевой символ, результирующая строка символов не заканчивается нулем, а возвращаемая длина не включает этот символ.
cJSON_CreateString()
ожидает нулевое значениеchar*
строкаПоэтому вам нужно либо:
- добавить +1 к параметру
num
calloc()
, чтобы учесть отсутствующий нулевой терминатор.
size_t wcsChars = wcslen(japanese[i].name);
size_t len = WideCharToMultiByte(CP_UTF8, 0, japanese[i].name, wcsChars, NULL, 0, NULL, NULL);
char* japanese_char = malloc(len + 1);
if (!japanese_char)
exit(EXIT_FAILURE);
WideCharToMultiByte(CP_UTF8, 0, japanese[i].name, wcsChars, japanese_char, len, NULL, NULL);
japanese_char[len] = '\0';
...
free(japanese_char);
- добавьте +1 к возвращаемому значению
wcslen()
или установите для параметра cchWideChar
WideCharToMultiByte()
значение -1, чтобы включить нулевой терминатор в вывод.
size_t wcsChars = wcslen(japanese[i].name) + 1;
size_t len = WideCharToMultiByte(CP_UTF8, 0, japanese[i].name, wcsChars, NULL, 0, NULL, NULL);
if (len == 0)
exit(EXIT_FAILURE);
char* japanese_char = malloc(len);
if (!japanese_char)
exit(EXIT_FAILURE);
WideCharToMultiByte(CP_UTF8, 0, japanese[i].name, wcsChars, japanese_char, len, NULL, NULL);
...
free(japanese_char);
size_t len = WideCharToMultiByte(CP_UTF8, 0, japanese[i].name, -1, NULL, 0, NULL, NULL);
if (len == 0)
exit(EXIT_FAILURE);
char* japanese_char = malloc(len);
if (!japanese)
exit(EXIT_FAILURE);
WideCharToMultiByte(CP_UTF8, 0, japanese[i].name, -1, japanese_char, len, NULL, NULL);
...
free(dest);