Длина, которую нужно передать mbstowcs()
, включает символ L'\0'
терминатора, но ваша расчетная длина в obj->length()
не включает его - вам нужно добавить 1 к значению, переданному mbstowcs()
.
Кроме того, вместо использования strlen(str)
для определения длины преобразованной строки следует использовать mbstowcs(0, src, 0) + 1
. Вы также должны изменить тип str
на const char *
и исключить состав. realloc()
может использоваться вместо пары free() / malloc()
. В целом, это должно выглядеть так:
typedef struct {
wchar_t *string;
size_t length;
} String;
void setCString(String *obj, const char *str)
{
obj->length = mbstowcs(0, src, 0);
obj->string = realloc(obj->string, (obj->length + 1) * sizeof(wchar_t));
size_t length = mbstowcs(obj->string, str, obj->length + 1);
printf("Length = %zu\n", length);
printf("!C string %s converted to wchar string %ls\n", str, obj->string);
if (length != wcslen(obj->string))
printf("Length failure!\n");
if (length == (size_t)-1)
{
//Conversion failed, set string to NULL terminated character
obj->string = realloc(obj->string, sizeof(wchar_t));
obj->string = L'\0';
}
else
{
//Conversion worked!
//do stuff
}
}
Марк Беннингфилд отмечает, что mbstowcs(0, src, 0)
является расширением POSIX / XSI стандарта C - чтобы получить необходимую длину только по стандарту C, вместо этого вы должны использовать:
const char *src_copy = src;
obj->length = mbstowcs(NULL, &src_copy, 0, NULL);