Windows 使用 UTF 16。Windows 控制台很可能不支持 UTF8。
将 UTF16 与宽字符串函数一起使用(wcsxxx
代替strxxx
)。然后您可以使用WideCharToMultiByte
将 UTF16 转换为 UTF8。例子:
#include <stdio.h>
#include <string.h>
#include <io.h> //for _setmode
#include <fcntl.h> //for _O_U16TEXT
int main()
{
_setmode(_fileno(stdout), _O_U16TEXT);
_setmode(_fileno(stdin), _O_U16TEXT);
wchar_t s[64];
fgetws(s, 64, stdin);
_putws(s);
return 0;
}
请注意,调用后不能使用 ANSI 打印函数_setmode(_fileno(stdout), _O_U16TEXT)
,必须重置。您可以尝试类似下面的函数来重置文本模式。
char* mygets(int wlen)
{
//may require fflush here, see _setmode documentation
int save = _setmode(_fileno(stdin), _O_U16TEXT);
wchar_t *wstr = malloc(wlen * sizeof(wchar_t));
fgetws(wstr, wlen, stdin);
//make UTF-8:
int len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, 0, 0, 0, 0);
if (!len) return NULL;
char* str = malloc(len);
WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, len, 0, 0);
free(wstr);
_setmode(_fileno(stdin), save);
return str;
}
void myputs(const char* str)
{
//may require fflush here, see _setmode documentation
int save = _setmode(_fileno(stdout), _O_U16TEXT);
//make UTF-16
int wlen = MultiByteToWideChar(CP_UTF8, 0, str, -1, 0, 0);
if (!wlen) return;
wchar_t* wstr = malloc(wlen * sizeof(wchar_t));
memset(wstr, 0, wlen * 2);
MultiByteToWideChar(CP_UTF8, 0, str, -1, wstr, wlen);
_putws(wstr);
_setmode(_fileno(stdout), save);
}
int main()
{
char* utf8 = mygets(100);
if (utf8)
{
myputs(utf8);
free(utf8);
}
return 0;
}