sfml和tgui使用中文乱码的问题

⌚Time: 2024-05-29 19:00:00

👨‍💻Author: Jack Ge

tgui是可以用于sfml的图形控件库,在tgui和sfml中使用中文会乱码。我尝试让tgui加载中文字体。但还是乱码

对于非ascii字符的显示,sfml官方教程里提到用宽字节字符串。

text.setString(L"中文");

对字符串用L前缀会让c++编译器生成Unicode字符串。

我尝试在tgui中使用这个办法,发现能够显示正常的中文字符串了。所以想要tgui能够显示中文,需要加载中文字体。然后使用L修饰字符串

m_gui.setGlobalFont("GUI/Fonts/wqy-microhei.ttc");//加载中文字体
...
m_textBox->setText(L"中文内容");//显示中文

上面的办法只能对字符串常量进行显示。如果是包含中文字符的变量,就需要使用多字节到宽字节的转换函数mbstowcs,网上的说明

对于 mbstowcs 函数来说,它需要知道多字节的编码类型才能正确的将其转换成宽字节的 unicode,很可惜这个编码类型并没有体现在函数的参数列表里,而是隐含依赖全局的 locale 。更加不幸的是,全局 locale 默认没有使用系统当前语言,而是设置为没什么用处的 “C” locale 。

所以在调用 mbstowcs 之前,先用 setlocale 将全局默认 locale 设为当前系统默认 locale,总之下面的办法实现了将多字节字符转化为中文宽字节字符(需要加载中文字体)

tsd::string text = "中文";//中文内容

setlocale(LC_ALL,"chs");//设置地域

size_t size = mbstowcs(NULL, text.c_str(), 0); // 获取转换后的宽字符字符串的长度
wchar_t* wideStr = (wchar_t*)malloc((size + 1) * sizeof(wchar_t)); // 为宽字符字符串分配内存
mbstowcs(wideStr, text.c_str(), size + 1); // 进行转换

m_textBox->setText(wideStr);//显示中文字符

free(wideStr);//释放空间

如果使用mbstowcs_s的代码是

setlocale(LC_ALL,"chs");

size_t size;
wchar_t* wideStr;
size_t wideSize;

size = mbstowcs_s(&wideSize, NULL, 0, text.c_str(), 0); 
wideStr = (wchar_t*)malloc((wideSize + 1) * sizeof(wchar_t)); 

mbstowcs_s(&size, wideStr, wideSize + 1, text.c_str(), wideSize); 

m_textBox->setText(wideStr);
free(wideStr);

也可以在程序中使用std::wstring字符串,一开始就用宽字符字符串就行了