mingw控制檯中文亂碼

亂碼緣由

直接先用一段話講亂碼緣由,看不懂老老實實就往下看吧html

其實我用Sublime或者VSCode等編輯器寫代碼出現的控制檯中文亂碼問題是編譯器mingw輸出的數據使用的是UTF-8編碼,而控制檯用了GBK編碼來解析它程序員

其實編碼只要統一,用UTF8或者GBK都行,但用了錯誤的編碼去解析文件就會出錯。算法

問題來源

若是咱們寫輕量代碼(好比寫算法題)也用VS之類的IDE,就太不划算了;雖然也有Codeblocks、Dev C++這樣的小一點的IDE,但用起來仍是能夠發現讓人很不爽的缺點。shell

以前嘗試用VS Code寫C++代碼,挺不錯的,好看方便。但問題就是難配置,最大的問題是控制檯中文亂碼,我搞了很久都沒搞好,今天終於解決了。json

在網上找到一段話是這麼講的:數組

Windows(中文)默認的字符集是Windows-936(GBK),mingw的內部是GCC,而GCC編譯器默認編譯的時候是按照UTF-8解析和輸出的,當未指定字符集時一概看成UTF-8進行處理,因而形成亂碼。編輯器

根據上邊這段話,我有點靈感,但仍是有疑問,見下。ide

問題分析

我電腦的CMD編碼設置的是UTF-8,代碼文件的編碼也是UTF-8,若是mingw默認按UTF-8處理的話,能夠看到這裏用的編碼全都是UTF-8,那應該不會出現亂碼的。測試

但咱們確實看到了亂碼啊!?優化

當我去看個人註冊表(見下圖),發現代碼連接、編譯後生成的可執行文件有一個單獨的註冊表,這彷佛說明咱們運行的可執行文件並非咱們口中的那個CMD(按Win+R、cmd打開的那個CMD)。因此@roadwide整理的網上的改CMD編碼啊什麼的,可能搞錯了問題的方向,不過也算一個方法吧,但彷佛對我不適用。我以前也是搞錯了方向。
Console註冊表.png

以下圖所示,咱們運行的可執行文件,也就是那個彈出來的控制檯,它的編碼是GBK。如今咱們應該知道亂碼的緣由了。

可執行文件編碼.png

整個過程是這樣的:

  1. 咱們代碼的編碼是UTF-8
  2. 把UTF-8編碼的代碼交給mingw,它也默認當作UTF-8處理(目前爲止這是正確的)
  3. mingw處理後生成的數據仍是UTF-8編碼(目前爲止仍是正確的)
  4. 把mingw處理後的數據(UTF-8編碼)給cmd(目前爲止也是正確的)
  5. cmd按GBK編碼處理它(UTF-8),這時出現錯誤,因此出現亂碼

解決方案

咱們能夠修改mingw的輸出,讓它在編譯時使用GBK編碼輸出,而後再讓CMD去顯示。


處理中文亂碼只須要設置兩個(核心只有一個)編譯參數,即在tasks.jsontasks中的args中添加-fexec-charset=GBK-finput-charset=UTF-8,下邊tasks.json中的第1四、15行。


這個解決方案中代碼文件的編碼是UTF-8,控制檯編碼是GBK,令mingw實現編碼轉換。

下面的.vscode配置是我在網上找到的比較新的VS Code配置,能夠做爲參考,具體不作解釋,想了解能夠去看文章末的參考網址。

tasks.json

// 用來編譯
{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "2.0.0",
    "tasks": [{
        "label": "Build",   // 任務的名字叫Build(編譯),注意是大小寫區分的,等會在launch中調用這個名字
        "type": "shell",    // 任務執行的是shell命令
        "command": "g++",   // 命令是g++
        "args": [           //參數
            "-g",           // 調試
            
            //
            "-fexec-charset=GBK",   // 處理mingw中文編碼問題
            "-finput-charset=UTF-8",// 處理mingw中文編碼問題
            //
            
            "${file}", //當前文件路徑,包括所在目錄絕對路徑和文件名
            "-o",      //對象名,不進行編譯優化
            "${fileDirname}/exes/${fileBasenameNoExtension}.exe", //當前目錄下exes文件夾下的exe文件,exe文件名爲 當前文件名(去掉擴展名).exe
        ],
        // 因此以上部分,就是在shell中執行下面這行語句(以我E盤中一個main.cpp爲例)
        // g++ -g  -fexec-charset=GBK -finput-charset=UTF-8 e:\Study\Programming\Code\Algo\PTABasicLevelCPP\main.cpp -o e:\Study\Programming\Code\Algo\PTABasicLevelCPP/exes/main.exe
        "group": {
            "kind": "build",
            "isDefault": true
            // 任務分組,tasks是個數組,意味着能夠執行多個task
            // 在build組的任務們,能夠經過在Command Palette(F1) 輸入run build task來運行
            // 固然,若是任務分組是test,你就能夠用run test task來運行 
        },
        "problemMatcher": [
            "$gcc" // 使用gcc捕獲錯誤
        ],
    }]
}

-fexec-charset=GBK是令mingw按GBK編碼生成exe文件。

-finput-charset=UTF-8是令mingw按UTF-8編碼處理。(經測試這個參數能夠不設置)

launch.json

{
    "version": "0.2.0",
    "configurations": [

        {
        "name": "C++ Launch (GDB)", // 調試時程序員看到的名字
        "preLaunchTask": "Build",   // launch以前會運行的任務,這個名字必定要跟tasks.json中的任務名一致
        "type": "cppdbg",           // 經測試,不可刪除
        "request": "launch",        // 經測試,不可刪除
        "program": "${fileDirname}/exes/${fileBasenameNoExtension}.exe", //運行當前打開文件的目錄下exes文件夾中名字和當前文件相同,但擴展名爲exe的程序
        "args": [],                 // 運行程序是默認是沒有參數的
        "stopAtEntry": false,       // 選爲true則會在打開控制檯後停滯,暫時不執行程序
        "cwd": "${workspaceFolder}",// 當前工做路徑:當前文件所在的工做空間
        "environment": [],
        "externalConsole": true,    // 是否使用外部控制檯,
        "MIMode": "gdb",
        "miDebuggerPath": "D:\\WorkingSoftware\\MinGW\\bin\\gdb.exe",   //調試器路徑
        "setupCommands": [{
            "description": "Enable pretty-printing for gdb",
            "text": "-enable-pretty-printing",
            "ignoreFailures": true
        }]
    }]
}
// https://code.visualstudio.com/Docs/editor/debugging#_launch-configurations
// author: huihut
// Available variables which can be used inside of strings.
// ${workspaceRoot}: the root folder of the team        
// ${file}: the current opened file                     
// ${fileBasename}: the current opened file's basename 
// ${fileDirname}: the current opened file's dirname    
// ${fileExtname}: the current opened file's extension  
// ${cwd}: the current working directory of the spawned process

參考連接

中文亂碼參考1

中文亂碼參考2

VS Code配置參考


做者:@臭鹹魚

轉載請註明出處:https://www.cnblogs.com/chouxianyu/

歡迎討論和交流!

相關文章
相關標籤/搜索