我试图找出一种从wchar_t*
类型的字符串转换为char
的方法,但由于某种原因无法使其正常工作。我用char
成功地完成了相反的操作(从wchar_t*
到mbsrtowcs()
),但这让我失望了。 man 3 wcsrtombs
中的返回值部分包含:
wcsrtombs()函数返回组成的字节数 转换了多字节序列的一部分,不包括终止 空字节。如果遇到一个不可能的宽字符 转换后,返回(size_t)-1,并将errno设置为EILSEQ。
考虑这个最小的例子:
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdbool.h>
#include <locale.h>
#include <wctype.h>
#include <wchar.h>
char *convert_to_multibyte(const wchar_t* arg, long num_chars) {
size_t buffer_size = num_chars * sizeof(wchar_t);
char *mb = malloc(buffer_size); // will waste some memory though
mbstate_t state;
wcsrtombs(NULL, &arg, 0, &state); // this supposedly will initialize the mbstate_t struct
size_t result;
result = wcsrtombs(mb, &arg, buffer_size, &state);
if (result == (size_t)-1) {
free(mb);
return NULL;
}
mb[buffer_size-1] = '\0';
return mb;
}
int main(int argc, char* argv[]) {
setlocale(LC_ALL, "fi_FI.UTF-8");
wchar_t test[] = L"ÄÄÄÄÖÖÖÖ";
char *converted = convert_to_multibyte(test, wcslen(test));
// printf("%s\n", converted);
return 0;
}
使用测试字符串L"ÄÄÄÄÖÖÖÖ"
,会返回(size_t) -1
,这意味着遇到了无法转换的宽字符 - 这不会发生在没有任何非字符串的字符串中ASCII字符。我在这里不理解什么?