首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >C++ 中文输出乱码?一篇博客彻底搞定!

C++ 中文输出乱码?一篇博客彻底搞定!

原创
作者头像
码事漫谈
发布于 2025-08-10 22:49:58
发布于 2025-08-10 22:49:58
5.4K0
举报
文章被收录于专栏:C++C++

关键词:C++、中文乱码、控制台编码、GBK、UTF-8、模板方法模式


1. 问题背景

今天在群里看到一段挺有趣的 C++ 代码,用模板方法模式描述传统放羊娃与现代放羊娃的一生:

每天放羊 → 卖羊赚钱 → 结婚 → 生孩子 → 孩子继续放羊……

代码写得没毛病,可一运行,终端里却蹦出一堆“口口口”或“烫烫烫”的乱码。

很多同学第一反应是“是不是代码写错了?”

其实,90% 的 C++ 中文乱码都不是代码问题,而是“编码不一致”导致的显示错位。


2. 复现场景

把简化后的代码贴出来,方便大家复现:

代码语言:cpp
复制
#include <iostream>

int main() {
    std::cout << "每天放羊..." << std::endl;
    std::cout << "卖羊赚钱..." << std::endl;
    std::cout << "用钱娶媳妇..." << std::endl;
    return 0;
}

期望输出:

代码语言:txt
复制
每天放羊...
卖羊赚钱...
用钱娶媳妇...

实际输出(Windows 默认 cmd):

代码语言:txt
复制
ÿþÿÿÿÿÿÿÿÿ...
¡¡¡¡...
ÓÃǮȢϱ¸¾...

3. 乱码成因

一句话总结:“源文件编码” ≠ “控制台编码”。

环节

常见编码

源文件(.cpp)

UTF-8(无 BOM)

Windows 控制台

默认代码页 936(GBK)

当编译器把 UTF-8 下的 每(0xE6 0xAF 0x8F)原封不动地交给控制台时,控制台按 GBK 去解码,于是 0xE6AF 被当成一个 GBK 字符,自然面目全非。


4. 解决方案

✅ 方案一:让控制台使用 UTF-8(推荐)

在 main() 里加两行,仅 Windows 有效:

代码语言:cpp
复制
#ifdef _WIN32
#include <cstdlib>
#endif

int main() {
#ifdef _WIN32
    system("chcp 65001");      // 切到 UTF-8 代码页
#endif
    std::cout << "每天放羊..." << std::endl;
    ...
}
  • 优点:undefined• 不改源文件编码,跨平台无感;undefined• VS / VSCode / CLion 通用;undefined• 不影响后续移植到 Linux/macOS。
  • 注意事项:undefined• 需确保源文件保存为 UTF-8 无 BOM(VSCode / CLion 默认即可)。undefined• Windows 7 以下老系统可能在 chcp 65001 后字体缺失,需手动把控制台字体改成“Lucida Console”或“Consolas”。
✅ 方案二:让源文件使用 GBK
  1. 用记事本 / VSCode / CLion 把 .cpp 另存为 → 编码选 GBK/ANSI。
  2. 无需改动代码,直接编译运行即可。
  • 缺点:undefined• 换到 Linux/macOS 或 CI 环境容易再次乱码;undefined• 团队协作时需统一编码;undefined• 与 CMake、Clang-Tidy 等工具链默认 UTF-8 冲突。
✅ 方案三:IDE 一键设置

IDE

操作路径

Visual Studio 2022

文件 → 另存为 → 保存按钮下拉 → “编码保存” → 简体中文(GB2312)

VSCode

右下角“UTF-8” → 重新打开带编码 / 另存为带编码 → GB2312

CLion

Settings → Editor → File Encodings → Global/Project Encoding → GBK


5. 完整示例(方案一)

代码语言:cpp
复制
#include <iostream>

#ifdef _WIN32
#include <cstdlib>
#endif

class ShepherdBoyLife {
public:
    void liveLife() {
        herdSheep();
        sellSheep();
        marry();
        haveChild();
        childGrowsUp();
    }
    virtual ~ShepherdBoyLife() = default;

protected:
    void herdSheep()   { std::cout << "每天放羊...\n"; }
    void sellSheep()   { std::cout << "卖羊赚钱...\n"; }
    virtual void marry() = 0;
    virtual void haveChild() = 0;
    void childGrowsUp() {
        std::cout << "孩子长大了...\n";
    }
};

class TraditionalShepherdBoy : public ShepherdBoyLife {
protected:
    void marry()      override { std::cout << "用钱娶媳妇...\n"; }
    void haveChild()  override { std::cout << "生儿育女...\n"; }
};

int main() {
#ifdef _WIN32
    system("chcp 65001 > nul");
#endif

    std::cout << "=== 传统放羊娃的一生 ===\n";
    TraditionalShepherdBoy boy;
    boy.liveLife();
    return 0;
}

6. 延伸阅读

  1. Windows 代码页一览:chcp 936(GBK)、chcp 65001(UTF-8)。
  2. C++20 起可用 std::format + std::print 直接输出 UTF-8,跨平台更省心。
  3. Linux/macOS 终端默认 UTF-8,一般无需额外设置。

7. 小结

问题

结论

代码有错吗?

没有,是编码不一致。

最快修复?

system("chcp 65001") + 源文件 UTF-8。

根治办法?

统一 源文件、编译器、终端 三者编码为 UTF-8。

把这篇博客收藏起来,下次再碰到 “C++ 中文乱码” 直接翻出来用就行!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 1. 问题背景
  • 2. 复现场景
  • 3. 乱码成因
  • 4. 解决方案
    • ✅ 方案一:让控制台使用 UTF-8(推荐)
    • ✅ 方案二:让源文件使用 GBK
    • ✅ 方案三:IDE 一键设置
  • 5. 完整示例(方案一)
  • 6. 延伸阅读
  • 7. 小结
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档