VSCode + GCC编译器(MinGW)开发环境中文字符乱码问题踩坑与解决办法

news2024/11/17 10:31:52

文章目录

      • 问题背景
      • 问题描述
        • 测试代码
        • 测试结果
        • 现象描述
        • 问题分析
      • 解决方案
        • 修改默认配置
          • 1. 已经存在的文件全部使用gbk编码重新保存。
          • 2. 在工程目录下新建`.vscode`目录,如果已存在则跳过此步骤。
          • 3. 在`.vscode`目录中新建`settings.json`,`launch.json`两个文件,已有则跳过。
          • 4. settings.json文件添加以下内容,使文件全部变成gbk编码:
          • 5. launch.json中修改以下内容,使用外置控制台运行编译后程序:
        • 修改后测试代码的运行结果

问题背景

在较长一段时间里,C/C++开发者所使用的集成开发环境(IDE)要么是比较重量级的VS(Visual Studio),要么是Codeblocks·、·Visual C++ 6.0等轻量级IDE,又或者是诸如notepad++、sublime text等文本编辑器+GCC编译器+命令行工具的组合式开发环境。这几种开发方式要么太过庞大比较吃硬件资源,比如VS动辄就要占用几十个G的硬盘空间,要么虽然轻量但是没有友好的代码提示和自动化的编译链接运行过程,开发体验并不是很友好。

近几年来,随着VSCode(Visual Studio Code)的流行,越来越多的开发者选择以此来作为个人的集成开发环境。使用VSCode开发C/C++程序可以下载安装VSCode官方的C/C++ for Visual Studio Code插件实现开发过程中的代码提示、调试、运行等功能,但是需要自行安装C/C++编译器,笔者是用的是GCC编译器MinGW。具体开发环境的搭建过程在此不作讲解,本文关注点在于开发过程中遇到的中文字符相关的乱码问题。

问题描述

测试代码

  1. 英文字符串文本文件 es_src.txt
Chinese
  1. 中文字符串文本文件 ch_src.txt
中文
  1. main.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
    char str_es[] = "Chinese";
    char str_ch[] = "中文";
    char str[30];

    // 读英文字符串的文本文件测试
    printf("读文件测试:\n");
    FILE *fpr_es = fopen("es_src.txt", "r");
    while (fgets(str, 30, fpr_es) != NULL)
    {
        printf("strcmp(%s, %s)=%d\n", str_es, str, strcmp(str_es, str));
    }
    fclose(fpr_es);

    // 直接打印含中文字符串测试
    printf("请输入英文字符串“Chinese”:\n");
    // 读入英文字符串
    scanf("%s", str);
    printf("直接打印测试:\n");
    // 直接打印英文字符串
    printf("str=%s\n", str);
    // 与英文字符串常量进行比较
    printf("strcmp(%s, %s)=%d\n", str_es, str, strcmp(str_es, str));

    // 英文字符串写入文件测试
    printf("写文件测试:\n");
    FILE *fpw_es = fopen("es_tar.txt", "w");
    fprintf(fpw_es, "%s\n%s\n", str_es, str);
    fclose(fpw_es);
    printf("写入完成!\n");

    // 读中文字符串的文本文件测试
    printf("读文件测试:\n");
    FILE *fpr_ch = fopen("ch_src.txt", "r");
    while (fgets(str, 30, fpr_ch) != NULL)
    {
        printf("strcmp(%s, %s)=%d\n", str_ch, str, strcmp(str_ch, str));
    }
    fclose(fpr_ch);

    // 直接打印中文字符串测试
    printf("请输入中文字符串“中文”:\n");
    // 读入中文字符串
    scanf("%s", str);
    printf("直接打印测试:\n");
    // 直接打印中文字符串
    printf("str=%s\n", str);
    // 与中文字符串常量进行比较
    printf("strcmp(%s, %s)=%d\n", str_ch, str, strcmp(str_ch, str));

    // 中文字符串写入文件测试
    printf("写文件测试:\n");
    FILE *fpw_ch = fopen("ch_tar.txt", "w");
    fprintf(fpw_ch, "%s\n%s\n", str_ch, str);
    fclose(fpw_ch);
    printf("写入完成!\n");

    system("pause");
    return 0;
}

测试结果

  1. 控制台输出结果
    可以看到
    (a) 从文件中读取英文字符串并打印可以正常显示;直接打印英文字符串常量和直接打印从键盘读入的英文字符串均正常显示,使用strcmp进行比较结果为0。
    (b) 从文件中读取中文字符串并打印可以正常显示;直接打印中文字符串常量可以正常显示,但是没有显示出从键盘读入的中文字符串,使用strcmp进行比较结果也不为0。
    在这里插入图片描述
读文件测试:
strcmp(Chinese, Chinese)=0 
请输入英文字符串“Chinese”:
Chinese
直接打印测试:
str=Chinese
strcmp(Chinese, Chinese)=0
写文件测试:
写入完成!
读文件测试:
strcmp(中文, 中文)=0      
请输入中文字符串“中文”:  
中文
直接打印测试:
str=
strcmp(中文, )=1
写文件测试:
写入完成!
Press any key to continue . . .
  1. 英文字符串文本文件 es_tar.txt
    英文字符串常量和从键盘读入的英文字符串均正常写入到文件中。
Chinese
Chinese

  1. 中文字符串文本文件 ch_tar.txt
    中文字符串常量正常写入到文件,而从键盘读入的中文字符串写入到文件中的是乱码
中文


现象描述

在使用VSCode + MinGW作为集成开发环境时,在不修改默认设置的情况下执行有中文字符的字符串操作时,通常会遇到以下几个问题:

  1. 直接打印含中文字符的字符串常量,比如printf("中文")或者printf("%s", "中文"),均可正常显示;但是打印由键盘读入的含中文字符的字符串时,如scanf("%s", str); printf("%s", str);,含中文字符的字符串str无法正常显示(不显示,或者显示为乱码)。
  2. 在读文件操作中,可以成功读入文本文件中的中文字符串,并且与中文字符串常量比较结果相等;但是在写文件操作中,写入文件的中文字符串常量能正常显示,但是由键盘读入的中文字符串则无法正常显示(不显示,或者显示为乱码)。

简而言之,从键盘读入的中文字符串无法正常显示和写入文件

问题分析

已知信息:

  1. Windows(中文)默认的字符集是Windows-936(GBK)。
  2. 默认配置下,VSCode使用其内置集成终端运行编译后的exe可执行文件,使用chcp命令可知此终端使用的字符集编码是65001,即UTF-8编码。
  3. 默认配置下,VSCode中新建的文件使用的编码也是UTF-8。
  4. 默认配置下,GCC编译器MinGW的内部默认编码是UTF-8。
    可能的原因:
    由键盘读入的中文字符串使用的是GBK编码,但是程序运行过程中使用的都是UTF-8编码。

解决方案

既然读入的中文字符是GBK编码无法修改,那就把其他相关的地方全都改成gbk编码即可。

修改默认配置

1. 已经存在的文件全部使用gbk编码重新保存。

修改文件编码1
修改文件编码2

2. 在工程目录下新建.vscode目录,如果已存在则跳过此步骤。
3. 在.vscode目录中新建settings.jsonlaunch.json两个文件,已有则跳过。
4. settings.json文件添加以下内容,使文件全部变成gbk编码:
{
    "files.encoding": "gbk"
}
5. launch.json中修改以下内容,使用外置控制台运行编译后程序:
{
    "configurations": [
        {
            ...
            "externalConsole": true,
            ...
        }
    ],
    "version": "2.0.0"
}

修改后测试代码的运行结果

  1. 控制台输出
    运行结果
读文件测试:
strcmp(Chinese, Chinese)=0
请输入英文字符串“Chinese”:
Chinese
直接打印测试:
str=Chinese
strcmp(Chinese, Chinese)=0
写文件测试:
写入完成!
读文件测试:
strcmp(中文, 中文)=0
请输入中文字符串“中文”:
中文
直接打印测试:
str=中文
strcmp(中文, 中文)=0
写文件测试:
写入完成!
请按任意键继续. . .
  1. es_tar.txt
Chinese
Chinese

  1. ch_tar.txt
中文
中文

以上为全部内容,欢迎批评指正。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/445536.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SAP CAP篇二:为Service加上数据库支持

在篇一快速创建一个Service&#xff0c;基于Java的实现中&#xff0c;可见使用SAP CAP &#xff08;Cloud Programming Model&#xff09;确实可以提高开发效率。尤其是Java技术栈上&#xff0c;对比于之前使用Olingo框架来实现oData&#xff0c;使用SAP CAP真的可以做到指数级…

Hightopo应邀参加 2023 第十届中国工业数字化论坛

3 月 30 日&#xff0c;以“加快数字化转型&#xff0c;助推高质量发展”为主题的第十届中国工业数字化论坛在北京隆重举行。厦门图扑软件科技有限公司&#xff08;以下简称“图扑软件”&#xff09;应邀参展&#xff0c;与诸位专家、领导、业界同仁共同研讨工业领域的数字化创…

红包算法关于---随机分发和平均分发

目录 群发普通红包 流程图 MainRedPacket类 Manager类 Member类 User类 群发普通红包 题目介绍 某软件有多名用户&#xff08;User类&#xff09;&#xff0c;某群聊中有群主&#xff08;Manager类&#xff09;和多名普通成员&#xff08;Member类&#xff09;&#x…

c++ 11 auto的概念和用法

目录 auto的概念&#xff1a; 使用auto声明变量的语法: auto关键字使用场景: 1.简化代码的书写和阅读 2.避免类型繁琐的重复定义 auto使用时的注意事项&#xff1a; auto的概念&#xff1a; 在C11标准中&#xff0c;auto是一种类型推导机制。它可以让编译器根据右值表达式…

代码随想录训练营day52|300、最长递增子序列;674、最长连续递增序列;718、最长重复子数组

300、最长递增子序列 给你一个整数数组 nums &#xff0c;找到其中最长严格递增子序列的长度。 子序列是由数组派生而来的序列&#xff0c;删除&#xff08;或不删除&#xff09;数组中的元素而不改变其余元素的顺序。例如&#xff0c;[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子…

【Spring Boot】SpringBoot 优雅整合Swagger Api 自动生成文档

文章目录 前言一、添加 Swagger 依赖二、创建接口类三、添加 Swagger 配置类四、访问 Swagger 页面五、整合一个更友好的UI接口文档 Knife4j1、添加 Knife4j 依赖2、添加 Knife4j 配置类3、访问 Knife4j 页面 总结 前言 Swagger 是一套 RESTful API 文档生成工具&#xff0c;可…

《选择》比努力更重要——C语言

目录 前言: 1.语句 2.选择语句 2.1小栗子 2.2选择结构 3.误导性else 3.1写法上的可读性和代码的稳健性&#xff1a; 3.2一些练习 4.switch选择语句 4.1嵌套的switch ❤博主CSDN:啊苏要学习 ▶专栏分类&#xff1a;C语言◀ C语言的学习&#xff0c;是为我们今后学习其…

Qt·DBus快速入门

目录 一、QtDBus简介 二、QtDBus类型系统 1、QtDBus类型系统简介 2、原生类型 3、复合类型 4、类型系统的使用 5、扩展类型系统 三、QtDBus常用类 1、QDBusMessage 2、QDBusConnection 3、QDBusInterface 4、QDBusReply 5、QDBusAbstractAdaptor 6、QDBusAbstract…

【Python_Opencv图像处理框架】图像阈值与滤波

写在前面 本篇文章是opencv学习的第二篇文章&#xff0c;主要讲解了图像的阈值和滤波操作&#xff0c;作为初学者&#xff0c;我尽己所能&#xff0c;但仍会存在疏漏的地方&#xff0c;希望各位看官不吝指正❤️ 写在中间 一、 图像阈值 &#xff08; 1 &#xff09;简单介绍…

扩散模型原理记录

1 扩散模型原理记录 参考资料&#xff1a; [1]【54、Probabilistic Diffusion Model概率扩散模型理论与完整PyTorch代码详细解读】 https://www.bilibili.com/video/BV1b541197HX/?share_sourcecopy_web&vd_source7771b17ae75bc5131361e81a50a0c871 [2] https://t.bili…

音视频通讯QoS技术及其演进

利用多种算法和策略进行网络传输控制&#xff0c;最大限度满足弱网场景下的音视频用户体验。 良逸&#xff5c;技术作者 01 什么是QoS&#xff1f;音视频通讯QoS是哪一类&#xff1f; QoS&#xff08;Quality of Service&#xff09;是服务质量的缩写&#xff0c;指一个网络能够…

MoE 系列(二)|Golang 扩展从 Envoy 接收配置

文&#xff5c;朱德江&#xff08;GitHub ID&#xff1a;doujiang24) MOSN 项目核心开发者蚂蚁集团技术专家 专注于云原生网关研发的相关工作 本文 1445 字 阅读 5 分钟 上一篇我们用一个简单的示例&#xff0c;体验了用 Golang 扩展 Envoy 的极速上手。 这次我们再通过一个…

这篇把「精准测试」算是讲明白了

作为测试同学&#xff0c;我们经常在工作中会有这样的困惑&#xff1a;我写的用例真的有效且全面吗&#xff0c;我的测试真的做到有效覆盖了吗&#xff1f;回归阶段我到底需要回归什么&#xff0c;回归验证充分吗&#xff1f;这次的改动到底影响范围有多大&#xff1f;针对以上…

JAVA集成强密码校验

JAVA集成强密码校验 1 : 背景2 : 代码设计编写2.1 : 引入规则配置2.2 : 密码校验工具类 3 : 验证4 : 相关链接 1 : 背景 最近系统需要做用户密码升级&#xff0c;增加强密码校验&#xff0c;密码长度&#xff0c;复杂度等等&#xff0c;所以整理了一份通用的密码复杂度控制代码…

你了解这2类神经性皮炎吗?常常预示着这5类疾病!

属于慢性皮肤病&#xff0c;患者皮肤可出现局限性苔藓样变&#xff0c;同时伴有阵发性瘙痒。神经性皮炎易发生在颈部两侧和四肢伸侧&#xff0c;中年人是高发人群。到目前为止神经性皮炎病因还并不是很明确&#xff0c;不过一部分病人发病前常常出现精神神经方面异常&#xff0…

SLAM 十四讲(第一版)各章方法总结与理解

SLAM 十四讲&#xff08;第一版&#xff09;各章方法总结与理解 总结十四讲中各章各步骤提到的各种方法&#xff0c;以及具体方法在哪个 c 库中可以调用。目的在于能更直观地了解 slam 过程各步骤到底在做什么&#xff0c;以及是怎么联系在一起的。 2. 初识 SLAM SLAM&#x…

ggplot作图中的图例处理方法

文章目录 改变坐标轴和图例的名称方法1, labs()方法2&#xff0c;scale_xxx_discrete/continuous() 删除坐标轴和图例的名称方法1&#xff0c; labs()方法2&#xff0c;scale_xxx_discrete/continuous()方法3&#xff0c;theme()方法4&#xff0c;guides()可以去图例名称 改变图…

怎么挣点零花钱,哪里可以赚点零花钱?以下这些方式值得参考一下

想赚零花钱的人群包括但不限于&#xff1a;大学生、宝妈/宝爸、自由职业者、比较有闲暇时间的上班族。 他们想要赚零花钱的原因不尽相同&#xff0c;但主要就是这几点&#xff1a;经济需求、个人发展、好奇心和乐趣等等。想赚取零花钱的人具有实际需求和个人发展的目标&#xf…

【hello C++】模板初阶

目录 1. 泛型编程 2. 函数模板 2.1 函数模板的概念 2.2 函数模板格式 2.3 函数模板的原理 2.4 函数模板的实例化 2.5 模板参数的匹配原则 3. 类模板 3.1 类模板的定义格式 3.2 类模板的实例化 4. STL简介 4.1 什么是STL 4.2 STL的版本 4.3 STL的六大组件 4.4 STL的重要性 4.5 …

基于.Net开发的ChatGPT客户端,兼容Windows、IOS、安卓、MacOS、Linux

2023年目前要说最热的点,肯定是ChatGPT了。 ChatGPT官方提供的网页版本,还有需要科学上网,很多人都会基于此进行封装。 现在是移动互联网时代,基于手机APP的需求还是很大的。 所以,今天给大家推荐一个ChatGPT客户端开源项目,兼容苹果和安卓手机、PC。 项目简介 这是…