根本原因是编码不匹配:Windows控制台用GBK,VSCode终端默认按UTF-8解析,而C程序未调用setlocale(LC_ALL, "")设置本地化,导致UTF-8中文被GBK终端错误解码为问号。

VSCode终端里printf中文显示为问号,根本原因是编码不匹配
Windows默认控制台(cmd/powershell)用的是GBK编码,而VSCode的集成终端默认按UTF-8读取输出——但C程序如果没显式设置本地化,printf会直接把UTF-8字节流扔给GBK终端,每个中文字符被拆成2–3个字节,每个字节又映射成一个无效字符(通常是?)。
必须在C代码开头调用setlocale,且参数不能写错
只加#include <locale.h></locale.h>不够,不调用setlocale或参数写成"Chinese""chs"之类,完全无效。Windows下唯一可靠写法是:
<pre class="brush:php;toolbar:false;">#include <stdio.h>
#include <locale.h>
int main() {
setlocale(LC_ALL, ""); // 关键:空字符串,继承系统区域设置
printf("你好,世界!\n");
return 0;
}
setlocale(LC_ALL, "")让C运行时自动读取Windows当前区域(控制面板→区域→管理→更改系统区域设置),通常就是<code>Chinese (GBK)- 不要用
setlocale(LC_CTYPE, "Chinese_China.936")这类硬编码——936是GBK代码页,但不同Windows版本可能有差异,空字符串最稳 - 必须放在
printf之前,且只能调用一次;重复调用可能失效
VSCode的launch.json和终端编码设置要同步
即使代码里setlocale正确,如果VSCode终端本身没切到GBK,还是乱码。两个地方要确认:
- 终端右下角点击编码标识(如
UTF-8),选GBK或GB2312,然后重启终端 - 在
.vscode/launch.json中,确保console字段不是integratedTerminal——它强制走VSCode终端编码逻辑;改用externalTerminal可绕过,但会弹cmd窗口 - 更推荐保留
integratedTerminal,但加上env环境变量:"env": {"CHCP": "936"}(不过实际生效依赖终端启动方式,不如手动切编码直接)
编译器和源文件保存编码也得是GBK
如果源文件本身用UTF-8保存(VSCode默认),而setlocale设的是GBK,printf会把UTF-8字节当GBK解码,结果仍是乱码。解决方法:
立即学习“C语言免费学习笔记(深入)”;
- VSCode右下角点击编码(如
UTF-8),选Reopen with Encoding → GBK,再保存文件 - 或者统一用UTF-8 +
setlocale(LC_ALL, ".65001")(65001是UTF-8代码页),但Windows旧版控制台不支持,容易失败 - Clang/GCC编译时加
-fexec-charset=GBK可指定执行字符集,但仅限GCC 11+,且VSCode默认用MinGW或MSVC,不一定支持
最稳的路径就一条:源文件存为GBK、代码第一句setlocale(LC_ALL, "")、VSCode终端手动切到GBK。三者缺一不可,少一个都会回到问号。


















