C++实现ANSI编码转换为UTF

您所在的位置:网站首页 ansi编码转utf8 C++实现ANSI编码转换为UTF

C++实现ANSI编码转换为UTF

2024-05-11 02:42| 来源: 网络整理| 查看: 265

文章结构:本文的先介绍了常见的几种编码格式:ANSI,Unicode,UTF-8,在进行编码转换之前,需要先判断文件的编码格式,在编码转换完成之后,需要将文件保存为UTF-8编码格式的文件。

文本文件编码格式介绍

在计算机内部,所有的数据都是以二进制的形式存储的。在存储文本时,需要把文本信息转换为二进制进行保存,而在显示时则需要把二进制转换为文本信息显示出来。编码就是二进制与显示的字符之间转行的规则。

ASCII

最开始是美国制定了一套字符编码,主要用来显示英文字符,称为ASCII(美国信息交换标准码),用一个字节来表示一个字符。

GBK

ASCII编码只适合用来显示英文字符,但是对于像中文这样6000多个常用汉字的语言来说,一个字节的大小完全不够用,所以中国就制定了一套自己的编码格式,每个汉字及符号使用两个字节表示。最开始是在1981年发布的GBK2312标准,后来又制定了GBK标准。

GBK编码,是在GB2312-80标准基础上的内码扩展规范,使用了双字节编码方案,其编码范围从8140至FEFE(剔除xx7F),共23940个码位,共收录了21003个汉字,完全兼容GB2312-80标准,支持国际标准ISO/IEC10646-1和国家标准GB13000-1中的全部中日韩汉字,并包含了BIG5编码中的所有汉字。GBK编码方案于1995年10月制定, 1995年12月正式发布,目前中文版的WIN95、WIN98、WINDOWS NT以及WINDOWS 2000、WINDOWS XP、WIN 7等都支持GBK编码方案。

ASNI

除了中国,其他许多国家也都制定了自己的编码标准,如日文的Shift-JS编码。为了使计算机支持多种语言,使用0x00~0x7F范围的一个字节表示一个英文字符,超出此范围的根据不同操作系统的语言进行编码,如在简体中文的操作系统中ASNI表示GBK编码,在日文操作系统中,ASNI表示Shift-JS编码。不同的ASNI编码之间互不兼容。

Unicode

由于不同的ANSI编码之间互不兼容,如果不容地区之间需要进行信息交互,就会经常需要进行编码转换,非常不方便。为了解决这个问题,ISO(国际标准化组织)制定了可以包含所有文字,符号的编码Unicode,Unicode规定用两个字节来统一表示所有字符,总共可以组合65532个字符。但是Unicode在制定的时候并没有考虑与其他编码格式兼容的问题,只能通过查表的方式来完成转换。

UTF-8

Unicode可以表示所有的字符,但是英文字符也与其他字符一样,使用两个字节进行编码,使得在保存英文文本的时候会多出一倍的存储空间,而大多数的文本信息都是英文的。尤其是在网络传输的时候,即使看到的页面的中文的网页,背后的代码也大多数的英文的。为了节省空间,提出一种可变长的编码方式UTF-8。

UTF-8编码规则:如果只有一个字节则其最高二进制位为0;如果是多字节,其第一个字节从最高位开始,连续的二进制位值为1的个数决定了其编码的字节数,其余各字节均以10开头。

虽然部分字符的表示UTF-8编码方式需要比Unicode编码方式的表示需要更多的字符, 但是英文却只需要一个字符,对于大部分文本信息是英文的文件来说, UTF-8的编码格式能够节省大量的空间。但是如果大部分的文本信息是中文的话,可能使用GBK编码更节省空间。 现在采用最多的编码方式就是UTF-8的编码方式。

检测文件编码

在转换文本文件的编码之前,需要先检测文件的编码,再进行转换。对于文本文件,需要判断的编码有:ANSI,Unicode,Unicode big endian, UTF-8 with BOM, UTF-8 without BOM。 其中,Unicode,Unicode big endian和UTF-8 with BOM的文件在文件头部有两个字节用来判断是什么编码格式,ANSI和UTF-8 with BOM文件则没有,需要对文本进行采样,统计分析后判断是哪一种编码。网上搜索说可以使用uchardet这个库来进行检测,但是本文是直接读取整个文件然后判断编码格式的。

text_encode check_text_encode(const string &file_name) { ifstream file_in(file_name, ios::binary); if (!file_in.is_open()) { cout 0) { return false; } if (b_all_ascii) { return false; } return true; } 编码转换与保存

ANSI编码可以转换为Unicode,Unicode可以转换为UTF-8,但是ANSI没办法直接转换为UTF-8,可以先将ANSI转换为Unicode,再将Unicode转换为UTF-8。 C++11标准库提供了方便转换编码的函数MultiByteToWideChar 将ANSI编码转换为Unicode

wstring ANSI2Unicode(const string &str) { int len = str.size(); int unicode_len = MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, NULL, 0); wchar_t *unicode_p = new wchar_t[unicode_len + 1]; memset(unicode_p, 0, (unicode_len) * sizeof(wchar_t)); MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, (LPWSTR)unicode_p, unicode_len); wstring str_w; str_w = (wchar_t *)unicode_p; delete unicode_p; return str_w; }

再将Unicode编码的文本保存为UTF-8编码的文本文件,

void save_as_utf8(string file_name, string content) { wstring content_unicode = ANSI2Unicode(content); wofstream ofs(file_name, ios::ate); //std::generate_header表示带BOM的UTF-8,std::little_endian表示不带BOM的UTF-8 //ofs.imbue(std::locale(ofs.getloc(), new std::codecvt_utf8)); ofs.imbue(std::locale(ofs.getloc(), new std::codecvt_utf8)); ofs


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3