zoukankan      html  css  js  c++  java
  • mingw控制台中文乱码

    乱码原因

    直接先用一段话讲乱码原因,看不懂老老实实就往下看吧

    其实我用Sublime或者VSCode等编辑器写代码出现的控制台中文乱码问题是编译器mingw输出的数据使用的是UTF-8编码,而控制台用了GBK编码来解析它

    其实编码只要统一,用UTF8或者GBK都行,但用了错误的编码去解析文件就会出错。

    问题来源

    如果我们写轻量代码(比如写算法题)也用VS之类的IDE,就太不划算了;虽然也有Codeblocks、Dev C++这样的小一点的IDE,但用起来还是可以发现让人很不爽的缺点。

    之前尝试用VS Code写C++代码,挺不错的,好看方便。但问题就是难配置,最大的问题是控制台中文乱码,我搞了好久都没搞好,今天终于解决了。

    在网上找到一段话是这么讲的:

    Windows(中文)默认的字符集是Windows-936(GBK),mingw的内部是GCC,而GCC编译器默认编译的时候是按照UTF-8解析和输出的,当未指定字符集时一律当作UTF-8进行处理,于是造成乱码。

    根据上边这段话,我有点灵感,但还是有疑问,见下。

    问题分析

    我电脑的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中的第14、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:StudyProgrammingCodeAlgoPTABasicLevelCPPmain.cpp -o e:StudyProgrammingCodeAlgoPTABasicLevelCPP/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/

    欢迎讨论和交流!


  • 相关阅读:
    LeetCode 382. Linked List Random Node
    LeetCode 398. Random Pick Index
    LeetCode 1002. Find Common Characters
    LeetCode 498. Diagonal Traverse
    LeetCode 825. Friends Of Appropriate Ages
    LeetCode 824. Goat Latin
    LeetCode 896. Monotonic Array
    LeetCode 987. Vertical Order Traversal of a Binary Tree
    LeetCode 689. Maximum Sum of 3 Non-Overlapping Subarrays
    LeetCode 636. Exclusive Time of Functions
  • 原文地址:https://www.cnblogs.com/chouxianyu/p/11249810.html
Copyright © 2011-2022 走看看