C++实现文件保存为ANSI/UTF-8/UCS-2文件

题记: 有时候 统一与规范可以解决很多问题。

曾经使用C++进行文件操作一直困惑我,为什么中文就乱码了呢?为什么在NotePad++上能够正常显示,然而在NotePad上显示行号就乱了呢?

解决上述问题,和题记相呼应,统一编码格式就能够解决所有的困惑。NotePad++支持多种编码,NotePad作为小弟自然比不上,现在让我一一介绍实现小弟支持的编码格式 ANSI, Unicode, Unicode big endian, UTF-8。

保存为ANSI编码文件

ANSI 的”Ascii”编码(American Standard Code for Information Interchange,美国信息互换标准代码)。

#include <iostream>
#include <fstream>
#include <locale>
using namespace std;

int main()
{
    // setlocale(LC_ALL, "zh_CN.UTF-8");
    // std::locale::global(std::locale("chs"));

    wstring content = L"[我是中国人! I'm a Chinese!我是中国人!";
    wofstream ofs("save_as_ansi.txt", ios::ate);
    ofs.write(content.c_str(), content.size());
    ofs.close();

    return 0;
}

OK,运行上面代码,你兴高彩烈打开“save_as_ansi.txt”,What!怎么只有一个 [ 可见,其实别慌,只需要反注释内容就正常显示了。

setlocale
头文件:locale.h
char* setlocale(int category, const char* locale)

设置所有C语言与本地环境相关的C函数的locale。当你傻傻分不清或不愿意去查到底哪些函数,在C++代码里加上它,就能解决潜在的问题。

std::locale::global:

头文件:locale
声 明:static locale global( const locale& loc );

替换全局 C++ 与本地环境相关的函数的locale, 返回系统原先的locale。

保存为UTF-8编码文件

实际上utf-8编码文件还可以分为包含BOM和无BOM两种文件,区分就在文件头。

实现它很麻烦,自从有了C11之后就很简单了,但是请不要在MAC OS7及其以下使用,因为系统根本不支持C11。你只能采用平台object-c的API实现了。

UTF_8_BOM

UTF-8 With Bom

#include <iostream>
#include <fstream>
#include <codecvt>
#include <locale>
using namespace std;

int main()
{
    wstring content = L"[我是中国人! I'm a Chinese!我是中国人!";
    wofstream ofs("save_as_utf_8_bom.txt", ios::ate);
    ofs.imbue(std::locale(ofs.getloc(), new std::codecvt_utf8<wchar_t, 0x10ffff, std::generate_header>));
    ofs << content;
    ofs.close();
    return 0;
}

UTF_8_NOBOM

UTF-8 Without Bom

#include <iostream>
#include <fstream>
#include <codecvt>
#include <locale>
using namespace std;

int main()
{
    wstring content = L"[我是中国人! I'm a Chinese!我是中国人!";
    wofstream ofs("save_as_utf_8_no_bom.txt", ios::ate);
    ofs.imbue(std::locale(ofs.getloc(), new std::codecvt_utf8<wchar_t, 0x10ffff, std::little_endian>));
    ofs << content;
    ofs.close();
    return 0;
}

区别仅在codecvt_utf8模板参数最后一位。

保存为Unicode编码文件

Unicode Big Endian

UCS-2 大端

#include <iostream>
#include <fstream>
#include <codecvt>
#include <locale>
using namespace std;

int main()
{
    wstring content = L"[我是中国人! I'm a Chinese!我是中国人!";
    wofstream ofs("save_as_ucs2_big.txt", ios::ate);
    ofs.imbue(std::locale(ofs.getloc(), new std::codecvt_utf16<wchar_t, 0x10ffff, std::generate_header>));
    ofs << content;
    ofs.close();
    return 0;
}

Unicode Little Endian

按照前面的思路,实现就很简单了,C11为你做好了,请看 std::codecvt_utf16

UCS-2 小端

#include <iostream>
#include <fstream>
#include <codecvt>
#include <locale>
using namespace std;

int main()
{
    wstring content = L"[我是中国人! I'm a Chinese!我是中国人!";
    wofstream ofs("save_as_ucs2_little.txt", ios::ate);
    ofs.imbue(std::locale(ofs.getloc(), new std::codecvt_utf16<wchar_t, 0x10ffff, (std::codecvt_mode)3>));
    ofs << content;
    ofs.close();
    return 0;
}

注意小端的模式掩码变为1|2,即:

enum codecvt_mode {
    consume_header = 4,
    generate_header = 2,
    little_endian = 1
};

尾语:我对C++的技能要求是能够熟练运用就好了。如果你要做语言编码库,或者更加底层的开发,那么请尽量阅读官方文档。以前是做C++开发,现在Python是我的主战场,做一名优秀的Pyhton开发者,朝着高级系统架构师发展。

加好友一起学习

如果你和我一样热爱开发,请加为好友,一起学习吧。如果你是单身女性开发者,加好友认识呗!。

1994-07

  • 1
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值