您的wcstombs_s() 代码将错误的值传递给sizeInBytes 参数:
sizeInBytes
mbstr 缓冲区的大小(以字节为单位)。
您传递的是japanese[i].name 的字符 计数,而不是japanese_char 分配的字节 计数。它们的值不同。
Unicode 代码点以 UTF-16 编码(wchar_t 字符串在 Windows 上编码为),每个使用 2 或 4 个字节,而在 UTF-8 中,每个使用 1-4 个字节,具体取决于它们的值。 U+0080..U+FFFF 范围内的 Unicode 代码点在 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);
由于您将显式大小传递给 cchWideChar 参数,因此您的 WideCharToMultiByte() 代码不是以空值结尾的 dest。
cchWideChar
lpWideCharStr 指示的字符串的大小(以字符为单位)。或者,如果字符串以 null 结尾,则可以将此参数设置为 -1。如果 cchWideChar 设置为 0,则函数失败。
如果此参数为 -1,则函数处理整个输入字符串,包括终止空字符。因此,生成的字符串有一个终止空字符,函数返回的长度包括这个字符。
如果此参数设置为正整数,则函数会精确处理指定数量的字符。如果提供的大小不包含终止空字符,则生成的字符串不是空终止字符,并且返回的长度不包含该字符。
cJSON_CreateString() 需要一个以 null 结尾的 char* 字符串。所以你需要:
- 为
calloc() 的num 参数添加+1 以说明缺少的空终止符。
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);
- 在
wcslen() 的返回值上加+1,或将WideCharToMultiByte() 的cchWideChar 参数设置为-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);