@[toc]
问题背景
在较长一段时间里,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。具体开发环境的搭建过程在此不作解说,本文关注点在于开发过程中遇到的中文字符相干的乱码问题。
问题形容
测试代码
-
英文字符串文本文件 es_src.txt
Chinese
-
中文字符串文本文件 ch_src.txt
中文
-
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; }
测试后果
- 控制台输入后果
能够看到
(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 . . .
-
英文字符串文本文件 es_tar.txt
英文字符串常量和从键盘读入的英文字符串均失常写入到文件中。Chinese Chinese
-
中文字符串文本文件 ch_tar.txt
中文字符串常量失常写入到文件,而 从键盘读入 的中文字符串写入到文件中的是 乱码。中文
景象形容
在应用 VSCode + MinGW 作为集成开发环境时,在不批改默认设置的状况下执行有中文字符的字符串操作时,通常会遇到以下几个问题:
- 间接打印含中文字符的字符串常量,比方
printf("中文")
或者printf("%s", "中文")
,均可失常显示;然而打印由键盘读入的含中文字符的字符串时,如scanf("%s", str); printf("%s", str);
,含中文字符的字符串 str 无奈失常显示(不显示,或者显示为乱码)。 - 在读文件操作中,能够胜利读入文本文件中的中文字符串,并且与中文字符串常量比拟后果相等;然而在写文件操作中,写入文件的中文字符串常量能失常显示,然而由键盘读入的中文字符串则无奈失常显示(不显示,或者显示为乱码)。
简而言之,从键盘读入的中文字符串无奈失常显示和写入文件。
问题剖析
已知信息:
- Windows(中文)默认的字符集是 Windows-936(GBK)。
- 默认配置下,VSCode 应用其内置集成终端运行编译后的 exe 可执行文件,应用
chcp
命令可知此终端应用的字符集编码是 65001,即 UTF- 8 编码。 - 默认配置下,VSCode 中新建的文件应用的编码也是 UTF-8。
-
默认配置下,GCC 编译器 MinGW 的外部默认编码是 UTF-8。
可能的起因:
由键盘读入的中文字符串应用的是 GBK 编码,然而程序运行过程中应用的都是 UTF- 8 编码。解决方案
既然读入的中文字符是 GBK 编码无奈批改,那就把其余相干的中央全都改成 gbk 编码即可。
批改默认配置
1. 曾经存在的文件全副应用 gbk 编码从新保留。
2. 在工程目录下新建
.vscode
目录,如果已存在则跳过此步骤。3. 在
.vscode
目录中新建settings.json
,launch.json
两个文件,已有则跳过。4. settings.json 文件增加以下内容,使文件全副变成 gbk 编码:
{"files.encoding": "gbk"}
5. launch.json 中批改以下内容,应用外置控制台运行编译后程序:
{ "configurations": [ { ... "externalConsole": true, ... } ], "version": "2.0.0" }
批改后测试代码的运行后果
-
控制台输入
读文件测试:strcmp(Chinese, Chinese)=0 请输出英文字符串“Chinese”:Chinese 间接打印测试:str=Chinese strcmp(Chinese, Chinese)=0 写文件测试:写入实现!读文件测试:strcmp(中文, 中文)=0 请输出中文字符串“中文”:中文 间接打印测试:str= 中文 strcmp(中文, 中文)=0 写文件测试:写入实现!请按任意键持续. . .
-
es_tar.txt
Chinese Chinese
-
ch_tar.txt
中文 中文
以上为全部内容,欢送批评指正。