您的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 指示的字符串的大小(以字符为单位)。或者,如果字符串以 null 结尾,则可以将此参数设置为 -1。如果 cchWideChar 设置为 0,则函数失败。
如果此参数为 -1,则该函数处理整个输入字符串,包括终止空字符。因此,结果字符串有一个终止空字符,函数返回的长度包括这个字符。
如果此参数设置为正整数,则该函数将精确处理指定数量的字符。如果提供的大小不包含终止空字符,则生成的字符串不是空终止字符,并且返回的长度不包含此字符。
cJSON_CreateString()
需要一个以 null 结尾的char*
字符串。所以你需要:
num
为参数添加 +1 以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);