C++字符编码转换详解

 2024-01-23 03:01:47  阅读 0

////

【CPP开发者入门】:在与东方语言(中文、日文、韩文)打交道时,我们经常会遇到各种编码问题,并被此类问题所困惑。 当我在网上查找资料时,我仍然一头雾水。 最后常常错误地解决问题,至今仍一头雾水。

本文介绍了如何在最常见的编码方式(UTF-8、ANSI)之间进行转换,并结合代码示例,清晰易懂,读者也可以直接使用示例。 本文推荐给经常处理文本字符串的程序员,以便他们掌握一些字符转换的基本方法。

以下为正文

在C++项目中,字符编码是一个很大的陷阱。 不同平台之间的编码往往是不同的。 如果用一组字符读取格式读取不同的编码格式,就会出现乱码。 因此,一般会转换为UTF-8,一种全平台且支持良好的编码格式。

,关于UTF-8的概念我就不过多解释了。 这里先说一下ANSI。 我第一次看到这个术语时,我以为它是 ASCII。 受到严厉批评。

ANSI 是一种字符代码。 为了使计算机能够支持更多的语言,通常用0x00~0x7F范围内的1个字节来表示一个英文字符。 超出这个范围,使用0x80~进行编码,即扩展ASCII编码。

不同的国家和地区制定了不同的标准,产生了各自的编码标准,如GBK、Big5、Big5等。 这些使用多个字节表示一个字符的各种汉字扩展编码方法称为 ANSI 编码。 在简体中文操作系统中,ANSI编码代表GBK编码; 在繁体中文操作系统中,ANSI编码代表Big5; 在日文操作系统中,ANSI编码代表编码。

以上内容摘自百度百科。 可见ANSI和ASCII还是有联系的。 ANSI 也称为本地代码。

我们需要能够在UTF-8和ANSI这三种编码格式之间自由转换。 如下所示:

c unicode编码转换中文_编码转换中文_十六进制编码转换中文

在C++中,如何做到这一点? 当然,我们使用标准库。 C++11仍然可以满足国际标准并提供这些接口。 如图中虚线所示,标准库没有提供UTF-8到ANSI的相互转换接口,但是我们可以自己封装转接接口,使用这条路径(UTF-8 ANSI)来实现。

因此,我们来谈谈UTF8和ANSI。

UTF8

我们先看代码:

std::string UnicodeToUTF8(const std::wstring & wstr){    std::string ret;    try {        std::wstring_convert< std::codecvt_utf8 > wcv;        ret = wcv.to_bytes(wstr);    } catch (const std::exception & e) {        std::cerr << e.what() << std::endl;    }    return ret;}std::wstring UTF8ToUnicode(const std::string & str){    std::wstring ret;    try {        std::wstring_convert< std::codecvt_utf8 > wcv;        ret = wcv.from_bytes(str);    } catch (const std::exception & e) {        std::cerr << e.what() << std::endl;    }    return ret;}

UTF-8 不是多字节字符串 ( ),而是宽字符串 ( )。

C++11提供了这个类,可以在and之间来回转换;

可以提供UTF-8编码规则。 该类位于 # 中。 随着宽字符串到多字节字符串的转换,转换规则由 提供。 这样UTF8和UTF8就可以互相转换了。

美国国家标准协会

std::string UnicodeToANSI(const std::wstring & wstr){    std::string ret;    std::mbstate_t state = {};    const wchar_t *src = wstr.data();    size_t len = std::wcsrtombs(nullptr, &src, 0, &state);    if (static_cast(-1) != len) {        std::unique_ptr< char [] > buff(new char[len + 1]);        len = std::wcsrtombs(buff.get(), &src, len, &state);        if (static_cast(-1) != len) {            ret.assign(buff.get(), len);        }    }    return ret;}std::wstring ANSIToUnicode(const std::string & str){    std::wstring ret;    std::mbstate_t state = {};    const char *src = str.data();    size_t len = std::mbsrtowcs(nullptr, &src, 0, &state);    if (static_cast(-1) != len) {        std::unique_ptr< wchar_t [] > buff(new wchar_t[len + 1]);        len = std::mbsrtowcs(buff.get(), &src, len, &state);        if (static_cast(-1) != len) {            ret.assign(buff.get(), len);        }    }    return ret;}

标准库提供了这两个函数,当然C标准库也提供了这两个函数。

接下来,该函数将宽字符串转换为多字节字符串。 编码规则受地区影响。 因此,该函数可以用于本地编码转换(与本地编码密切相关)。

因此,关于本地代码的使用,需要在代码中添加如下语句:

(,“”);

目的是使本地代码有效。 这段代码的作用是让C++语言(区域)和本地区域一致。 Linux下可以运行命令查看:

c unicode编码转换中文_十六进制编码转换中文_编码转换中文

可以看到,=en_US.UTF-8,表示英语,英国,UTF-8编码,表示本地编码是这个。

当然,你也可以在其中指定一些编码规则,并将其转换为其他编码。 但不建议这样做,因为它是全局的,设置它会影响其他地方的编码。

四个参数的含义是什么?

std:: ( char* dst, const ** src, std:: len, std::* ps );

注意:如果dst ==,此时的返回值表示会生成这么多字节。 因此,我们可以得到这个返回值来创建一个新的数组来存储new char[len + 1]。 因此,通常会调用两次。

同样的原因。

UTF-8 ANSI

我觉得中介只是在假装。

std::string UTF8ToANSI(const std::string & str){    return UnicodeToANSI(UTF8ToUnicode(str));}std::string ANSIToUTF8(const std::string & str){    return UnicodeToUTF8(ANSIToUnicode(str));}

总结

C++11标准库相当强大。 尽管它如此强大,但许多功能仍然未知。 所以,你还是需要拓宽你的视野。 否则,你就不知道如何使用好东西,你就会陷入困境。

顺便说一句,Linux下添加(,“”)后,程序就可以在命令行中正常显示了。 如果不添加的话,可能无法正常显示。 原因是(,"")也会影响cout,cout是全局的; 但在Linux下无法显示。 显示正常,不知道为什么,但是在调试过程中,观察到正常结果; 我没有做过任何实验,但应该没问题。

关于C++字符编码,欢迎在评论中与我讨论。 如果您觉得文章不错,请点赞阅读,支持我继续分享好文章。 谢谢!

标签: 编码 字符 字节

如本站内容信息有侵犯到您的权益请联系我们删除,谢谢!!


Copyright © 2020 All Rights Reserved 京ICP5741267-1号 统计代码