MinGW 沒辦法用 setlocale 設定字符集 (出現亂碼) ??

来源:9-10 宽字符串与窄字符串的转换

Haowei Hsu

2021-01-06

老師在視頻中示範了 MSVC 的寬窄字符亂碼的處理:

(1) 源文件用utf-8來儲存
(2) 在編譯器選項中加入 "/utf-8"
(3) setlocale(LC_ALL, "zh_CN.utf-8")

的確能夠輸出正確的中文字符。如圖:
图片描述

可是我將環境換成 MinGW 後,並在編譯器選項中加入:

(1) -finput-charset=utf-8
(2) -fexec-charset=utf-8
(3) -fwide-exec-charset=utf-16le

結果卻出現亂碼?? 而且我發現 setlocale 回傳的是 NULL,代表裡面的參數設錯了??? 如圖:
图片描述

写回答

4回答

bennyhuo

2021-01-06

mingw 确实不支持 setlocale ,不用跟他较劲了

1
3
Haowei Hsu
非常感谢! # 這裡給這個問題做個總結好了: 1. MinGW的setlocale的第二個參數: (1) 不支持"zh_CN"、"en_US"這種地區寫法。 (2) 解決亂碼主要是設定字碼頁".936"、".65001"、".950"。 (3) 但不支持utf-8(".65001")的邊碼(即使Windows有utf-8的字碼頁)。 2. 如果要寫在Windows上運行的程序,最好用MSVC來編譯。
2021-01-09
共3条回复

Haowei Hsu

提问者

2021-01-09

老師,我發現:

MinGW的 setlocale 是可以設定第二個參數的。

只不過好像不支持 "zh_CN" 這種地區寫法。

如果寫"cht"、"chinese"...等,setlocale就不會回傳NULL了。

如果要指定終端執行運行時的編碼方式,就輸入".950"、".936"...等等

但是,我輸入了UTF-8的字碼頁".65001"後,卻依然回傳了NULL。

//img.mukewang.com/szimg/5ff96e6d094cd54018100752.jpg

//img.mukewang.com/szimg/5ff96e71090c95b518080755.jpg

後來我在一個英文頁面上看到有人說: 

MinGW的setlocale不支持utf-8的邊碼 (雖然Windows的utf-8字碼頁是存在的)

如果真的是這樣,那估計就真的沒辦法了。

//img1.sycdn.imooc.com/szimg/5ff96f0e0966db3506910219.jpg

0
2
bennyhuo
研究得很细致,给你按赞
2021-01-09
共2条回复

bennyhuo

2021-01-07

用 mac 做了下实验,比较符合预期://img.mukewang.com/szimg/5ff65243095ad47011481360.jpg

//img.mukewang.com/szimg/5ff6524f0951f81804920276.jpg

MinGW 默认的 locale 应该跟系统自己的设置有关系,但目前没有办法直接修改,因此表现出来的比较奇怪。这部分暂时先了解即可。如果遇到需要解决的场景,可以使用 Windows 的 api 做转换,例如:https://docs.microsoft.com/en-us/windows/win32/api/stringapiset/nf-stringapiset-multibytetowidechar

转换时可以指定编码类型,避免与 locale 直接产生依赖:MultiByteToWideChar(CP_UTF8, 0, e.what(), (int)strlen(e.what()), &wideWhat[0], (int)wideWhat.size());

这个函数我们在 16章处理下载文件名的cjk字符时也有用到。

0
0

Haowei Hsu

提问者

2021-01-06

所以 mingw 無法打印寬字符的中文嗎?

0
4
Haowei Hsu
回复
bennyhuo
關於 "是不是和 CLion 有關係" 這點,我其實之前有注意到在 CLion 中 Run 和 Debug 在執行時所使用的終端編碼好像有不同。(Debug好像是使用utf-8,而Run似乎是根據Windows預設的字符集邊碼) 不過我打算之後另開一個問題貼再問,因為我還在整理中....
2021-01-08
共4条回复

C语言系统化精讲 重塑编程思想 打造坚实的开发基础

如果通向大牛的道路有捷径,那就是先学好C语言

2208 学习 · 853 问题

查看课程