Я пытался преобразовать ввод китайских символов из командной строки Windows в Big5 в UTF-8, сначала преобразовав полученный ввод в char32_t
в кодировке UTF-32, а затем преобразовать его в UTF-8. Я вызывал функцию mbtoc32
из <uchar.h>
, чтобы выполнить эту работу, однако она продолжала посылать «Ошибка кодирования».
Ниже приведены условия, с которыми я столкнулся:
- Преобразование последовательности (Big5) в представление
wchar_t
с помощью mbstowcs
выполнено успешно. mbrtoc32
принимает многобайтовую последовательность как UTF-8, а языковой стандарт - нет. (Установите на ""
, возвращает "Китайский (традиционный) _Hong Kong SAR.950" на моей машине)
Ниже приведен код, который я писал попытаться отладить мою проблему, однако безуспешно. Он пытается преобразовать "香" китайский символ (U + 9999) в многобайтовое представление, затем пытается преобразовать кодировку Big5 "香" (0xADBB) в wchar_t
и char32_t
. Однако преобразование из многобайтового (Big5) в char32_t
возвращает ошибку кодирования. (В отличие от этого, ввод последовательности UTF-8 «香» в mbrtoc32
действительно возвращает 0x9999 успешно)
#include <uchar.h>
#include <stdio.h>
#include <locale.h>
#include <stdlib.h>
mbstate_t state;
int main(void){
setlocale(LC_CTYPE, "");
printf("Your locale is: %s\n", setlocale(LC_CTYPE, NULL));
char32_t chi_c = 0x9999;
printf("Character U+9999 is 香\n");
char *mbc = (char *)calloc(32, sizeof(char));
size_t mb_len;
mb_len = c32rtomb(mbc, chi_c, &state);
int i;
printf("The multibyte representation of U+9999 is:\n");
// 0xE9A699, UTF-8
for (i = 0; i < mb_len; i++){
printf("%#2x\t", *(mbc + i));
}
char *src_mbs = (char *)calloc(32, sizeof(char));
// "香" in Big5 encoding
*(src_mbs + 0) = 0xad;
*(src_mbs + 1) = 0xbb;
wchar_t res_wc;
mbtowc(&res_wc, src_mbs, 32); // Success, res_wc == 0x9999
char32_t res_c32;
mb_len = mbrtoc32(&res_c32, src_mbs, (size_t)3, &state);
// Returns (size_t)-1, encoding error
if (mb_len == (size_t)-1){
perror("Encoding error");
return errno;
}
else {
printf("\nThe 32-bit character representation of U+9999 is:\n%#x", res_wc);
}
return 0;
}
Я также прочитал документацию из cppreference.com , как говорится,
В любом случае многобайтовая кодировка символов, используемая этой функцией, определяется текущей активной C локалью.
I ожидайте, что mbrtoc32
будет вести себя как mbtowc
, который преобразует символ из кодировки c, заданного для локали, в UTF-32 (в данном случае Big5 в UTF-32).
Есть ли какие-либо решения для использования mbrtoc32
для преобразования многобайтового символа в char32_t
без «ошибки кодирования»?
PS: я использую Mingw-64 на Windows 10, составлено с помощью g cc.