一文带你彻底搞定C++中文输出乱码的问题

 更新时间:2025年10月27日 08:19:20   作者:m0_74823364  
这篇文章主要为大家详细介绍了C++中文输出乱码的相关解决方法,文中的示例代码讲解详细,具有一定的借鉴价值,有需要的小伙伴可以了解下

1. 问题背景

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

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

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

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

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

2. 复现场景

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

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

期望输出:

每天放羊...
卖羊赚钱...
用钱娶媳妇...

实际输出(Windows 默认 cmd):

ÿþÿÿÿÿÿÿÿÿ...
¡¡¡¡...
ÓÃǮȢϱ¸¾...

3. 乱码成因

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

环节常见编码
源文件(.cpp)UTF-8(无 BOM)
Windows 控制台默认代码页 936(GBK)

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

4. 解决方案

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

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

#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

用记事本 / VSCode / CLion 把 .cpp 另存为 → 编码选 GBK/ANSI

无需改动代码,直接编译运行即可。

缺点:undefined• 换到 Linux/macOS 或 CI 环境容易再次乱码;undefined• 团队协作时需统一编码;undefined• 与 CMake、Clang-Tidy 等工具链默认 UTF-8 冲突。

方案三:IDE 一键设置

IDE操作路径
Visual Studio 2022文件 → 另存为 → 保存按钮下拉 → “编码保存” → 简体中文(GB2312)
VSCode右下角“UTF-8” → 重新打开带编码 / 另存为带编码 → GB2312
CLionSettings → Editor → File Encodings → Global/Project Encoding → GBK

5. 完整示例(方案一)

#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. 延伸阅读

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

到此这篇关于一文带你彻底搞定C++中文输出乱码的问题的文章就介绍到这了,更多相关C++中文输出乱码解决内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++分析类的对象作类成员调用构造与析构函数及静态成员

    C++分析类的对象作类成员调用构造与析构函数及静态成员

    终于到了对象的初始化和清理的最后阶段了,在这里分享一个cpp里有多个类时,一个类的对象作为另一个类成员的时候构造函数和析构函数调用的时机。还有一个静态成员也是经常考到的点,在这篇博客将会详解其概念并举出案例巩固,让我们开始
    2022-05-05
  • OpenCV获取图像中直线上的数据具体流程

    OpenCV获取图像中直线上的数据具体流程

    对图像进行处理时,经常会有这类需求:客户想要提取出图像中某条直线或者ROI区域内的感兴趣数据,进行重点关注,怎么操作呢,下面小编通过实例代码介绍下OpenCV获取图像中直线上的数据,一起看看吧
    2021-11-11
  • C语言中的fscanf()函数与vfscanf()函数使用

    C语言中的fscanf()函数与vfscanf()函数使用

    这篇文章主要介绍了C语言中的fscanf()函数与vfscanf()函数使用,是C语言入门学习中的基础知识,需要的朋友可以参考下
    2015-08-08
  • C语言指针入门学习面面观

    C语言指针入门学习面面观

    这篇文章主要介绍了C语言指针的一些基础知识,指针可以说是C语言入门学习中的头等大事,文中从数组和函数等多方面剖析C中指针的作用,需要的朋友可以参考下
    2016-02-02
  • Qt学习教程之对话框消失动画效果

    Qt学习教程之对话框消失动画效果

    这篇文章主要给大家介绍了关于Qt学习教程之对话框消失动画效果的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-07-07
  • VSCode保存代码自动格式化无效的解决方法

    VSCode保存代码自动格式化无效的解决方法

    最近一直使用vscode,VSCode中各种配置后,自动保存格式化仍然无效,本文就来介绍一下解决方法,感兴趣的可以了解一下
    2023-08-08
  • C语言的动态内存管理你了解吗

    C语言的动态内存管理你了解吗

    这篇文章主要为大家详细介绍了C语言的动态内存管理,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-03-03
  • 使用C语言实现绘制立体分离式环图

    使用C语言实现绘制立体分离式环图

    这篇文章主要为大家详细介绍了使用C语言实现绘制立体分离式环图的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-03-03
  • C语言学习之柔性数组详解

    C语言学习之柔性数组详解

    结构体的最后一个元素允许是未知大小的数组,这就叫柔性数组。这篇文中主要为大家详细介绍了C语言中柔性数组的相关知识,需要的可以了解一下
    2023-03-03
  • C++读取带空格字符串的方法

    C++读取带空格字符串的方法

    今天小编就为大家分享一篇C++读取带空格字符串的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-07-07

最新评论