1.三种编码的回顾

Ansi字符串我们最熟悉,英文占一个字节,汉字2个字节,以一个/0结尾,常用于txt文本文件。 
Unicode字符串,每个字符(汉字、英文字母)都占2个字节;在VC++的世界里,Microsoft比较鼓励使用Unicode,如wchar_t。 
UTF8是Unicode一种压缩形式,英文A在unicode中表示为0x0041,英语中这种存储方式太浪费,因为浪费了50%的空间,于是就把英文压缩成1个字节,成了utf8编码;但是汉字在utf8中占3个字节,显然用做中文不如ansi合算,这就是中国的网页用作ansi编码而国外的网页常用utf8的原因。程序中把15.7M大小UTF8格式的txt文件转化为ANSI后,大小仅为10.8M。

2.转换函数

一般情况下,可以通过Windows头文件下的两个函数实现各个类型之间的转换。头文件添加:

#include <Windows.h>

多字节字符集 -> Unicode字符集

int MultiByteToWideChar(  __in   UINT CodePage, // 标识了与多字节关联的一个代码页值  __in   DWORD dwFlags, // 允许我们进行额外的控制,它会影响带变音符号(比如重音)的字符。但是一般情况下不适用,赋为 0 即可。  __in   LPCSTR lpMultiByteStr, // 参数指定要转换的字符串  __in   int cbMultiByte, // 指定要转换串长度的长度(字节数),如果参数值是-1,函数便可自动判断源字符串的长度  __out  LPWSTR lpWideCharStr, // 指定转换后Unicode版本的字符串内存地址  __in   int cchWideChar        // 指定 lpWideCharStr 缓冲区的最大长度。                                // 如果传入0,函数不会进行转换,而是返回一个宽字符数(包括终止字符'/0'),                // 只有当缓冲区能够容纳该数量的宽字符时,转换才会成功。);

Unicode字符集 –> 多字节字符集

int WideCharToMultiByte(  __in   UINT CodePage,   // 标志了要与新转换的字符串关联的代码页  __in   DWORD dwFlags,   // 制定额外的转换控制,一般不需要进行这种程度的控制,而为 dwFlag 传入 0  __in   LPCWSTR lpWideCharStr, // 指定要转换的字符串的内存地址  __in   int cchWideChar,       // 指出该字符串的长度,如果传入 -1 ,则由函数来判断字符串的长度  __out  LPSTR lpMultiByteStr,  // 转换后的缓冲区  __in   int cbMultiByte,       // 指定 lpMultiByteStr 缓冲区的最大大小(字节数),如果传入 0 ,函数返回该目标缓冲区需要的大小  __in   LPCSTR lpDefaultChar,    __out  LPBOOL lpUsedDefaultChar // 宽字符字符串中,如果至少有一个字符不能转换为对应的多字节形式,函数就会把这个变量设为 TRUE 。如果所有字符都能成功转换,就会把这个变量设为 FALSE。 通常将此函数传入 NULL 值。);

只有一个字符在 CodePage 制定的代码页中没有对应的表示时,WideCharToMultiByte 才会使用后两个参数。在遇到一个不能转换的字符时,函数便使用 lpDefaultChar 参数指向的字符。如果这个参数指向为 NULL ,函数就会使用一个默认的字符。这个默认的值通常是一个问号。这对文件操作是非常危险的,因为问号是一个通配符。

3.程序实现

程序的头文件:

/* *作者:侯凯 *说明:utf8、unicode、utf8相互转化 *日期:2013-6-4*/#include <iostream>#include <string>#include <fstream>#include <Windows.h> //Windows头文件using std::string;using namespace std;

ANSI转Unicode

void AnsiToUnicode() {    char* sAnsi = "ANSI to Unicode, ANSI 转换到 Unicode";    //ansi to unicode    int sLen = MultiByteToWideChar(CP_ACP, NULL, sAnsi, -1, NULL, 0);     wchar_t* sUnicode = new wchar_t[sLen];    //wchar_t* sUnicode = (wchar_t*)malloc(sLen*sizeof(wchar_t));    MultiByteToWideChar(CP_ACP, NULL, sAnsi, -1, sUnicode, sLen);     ofstream rtxt("ansitouni.txt");    rtxt.write("/xff/xfe",2);//原因参见上一篇——"小尾"字节序方式存储    rtxt.write((char*)sUnicode, sLen*sizeof(wchar_t));    rtxt.close();    delete[] sUnicode;     sUnicode =NULL;     //free(sUnicode);}

Unicode转ANSI

void UnicodeToAnsi() {    wchar_t *sUnicode = L"Convert Unicode to ANSI, Unicode 转换为 ANSI";    //unicode to ansi    int sLen = WideCharToMultiByte(CP_ACP, NULL, sUnicode, -1, NULL, 0, NULL, NULL);     char* sAnsi = new char[sLen];    //char* sAnsi = (char*)malloc(sLen);    WideCharToMultiByte(CP_ACP, NULL, sUnicode, -1, sAnsi, sLen, NULL, NULL);     ofstream rtxt("unitoansi.txt");    rtxt.write(sAnsi, sLen);    rtxt.close();    delete[] sAnsi;     sAnsi =NULL;     //free(sAnsi);}

Unicode转UTF8

void UnicodeToUtf8(){    wchar_t *sUnicode = L"Convert Unicode to UTF8, Unicode 转换为 UTF8";     // unicode to UTF8     int sLen = WideCharToMultiByte(CP_UTF8, NULL, sUnicode, -1, NULL, 0, NULL, NULL);     //UTF8虽然是Unicode的压缩形式,但也是多字节字符串,所以可以以char的形式保存     char* sUtf8 = new char[sLen];      //unicode版对应的strlen是wcslen     WideCharToMultiByte(CP_UTF8, NULL, sUnicode, -1, sUtf8, sLen, NULL, NULL);     ofstream rtxt("unitoutf8.txt");    rtxt.write("/xef/xbb/xbf", 3);//原因参见上一篇    rtxt.write(sUtf8, sLen);    rtxt.close();    delete[] sUtf8;     sUtf8 =NULL; }

UTF8转Unicode

void Utf8ToUnicode(){        //UTF8 Convert to Unicode, UTF8 转换为 Unicode,用UE十六进制打开“转化为”直接复制过来乱码,用16进制表示    char* sUtf8 = "UTF8 Convert to Unicode, UTF8 /xe8/xbd/xac/xe6/x8d/xa2/xe4/xb8/xba Unicode";     //UTF8 to Unicode     int sLen = MultiByteToWideChar(CP_UTF8, NULL, sUtf8, -1, NULL, 0);     wchar_t* sUnicode = new wchar_t[sLen];     MultiByteToWideChar(CP_UTF8, NULL, sUtf8, -1, sUnicode, sLen);    ofstream rtxt("utf8touni.txt");    rtxt.write("/xff/xfe",2);    rtxt.write((char*)sUnicode, sLen*sizeof(wchar_t));    rtxt.close();    delete[] sUnicode;     sUnicode =NULL;  }

Ansi转换utf8和utf8转换Ansi就是上面2个的结合,把unicode作为中间量,进行2次转换即可。

4.UTF8转ANSI

在网络传输中,我们常常使用UTF8编码,但在程序处理时,我们习惯于ANSI编码,至少目前的VS2010对UTF8码的显示是乱码的。以下函数综合上述程序,实现了txt文件UTF8编码向ANSI编码的转化。

//changeTxtEncoding修改字符串的编码  char* changeTxtEncoding(char* szU8){      int wcsLen = ::MultiByteToWideChar(CP_UTF8, NULL, szU8, -1, NULL, 0);      wchar_t* wszString = new wchar_t[wcsLen];    ::MultiByteToWideChar(CP_UTF8, NULL, szU8, -1, wszString, wcsLen);    cout<<wszString<<endl;    int ansiLen = ::WideCharToMultiByte(CP_ACP, NULL, wszString, -1, NULL, 0, NULL, NULL);  //wcslen(wszString)    char* szAnsi = new char[ansiLen];      ::WideCharToMultiByte(CP_ACP, NULL, wszString, -1, szAnsi, ansiLen, NULL, NULL);     delete[] wszString;    return szAnsi;  }void changeTextFromUtf8ToAnsi(const char* filename)  {      ifstream infile;    string strLine="";    string strResult="";      infile.open(filename);    infile.seekg(3, ios::beg);    if (infile)      {          while(!infile.eof())        {              getline(infile,strLine);              strResult+=strLine+"/n";        }      }    infile.close();    char* changeTemp=new char[strResult.length()+1];    changeTemp[strResult.length()]='/0'; //问题记录    strcpy(changeTemp, strResult.c_str()); //const char*转化char*的方法    char* changeResult=changeTxtEncoding(changeTemp);     strResult=changeResult;      ofstream outfile;      outfile.open("ANSI.txt");      outfile.write(strResult.c_str(), strResult.length());      outfile.flush();      outfile.close();    delete[] changeResult;    delete[] changeTemp;}

问题记录: 
关于字符串的长度a.String类型的length()和size()函数都返回字符串的真实大小,不包括'/0‘ ; 
b.char*类型的strlen()函数也是返回字符串的真实大小,不包括'/0‘ ; 
c.注意,sizeof()函数包含'/0‘ ,如char str[] = “Hello” ;则sizeof (str ) = 6。

Ansi,UTF8,Unicode编码相关推荐

  1. VB 文件编码互换模块(支持 Ansi,UTF-8,Unicode(little endian),Unicode big endian)

    'VB 文件编码互换模块,支持对Ansi,UTF-8,Unicode(little endian),Unicode big endian编码之间进行转换. Option Explicit Privat ...

  2. Ansi与Unicode编码

    视频教程: Ansi与Unicode编码 大家在编程时经常遇到的数据类型: ● Ansi: char   代表一个字符  (CHAR) char *  代表一个字符串指针   (PCHAR    PS ...

  3. C语言实现gbk/utf8/unicode编码转换

    细说:Unicode, UTF-8, UTF-16, UTF-32, UCS-2, UCS-4 Unicode与UTF-8互转(C语言实现) 不依赖任何系统API,用c语言实现gbk/utf8/uni ...

  4. utf8mb4 字符集(4字节 UTF-8 Unicode 编码)

    最近做项目遇到APP评论中有 emoji 表情符号,结果导致插入 MySQL 数据库失败,找到 MySQL 官方相关内容,这里斗胆翻译一下.在翻译过程中有些不明白的地方,如BMP.collation等 ...

  5. unicode,ansi,utf-8,unicode big endian编码的区别

    为什么80%的码农都做不了架构师?>>>    随便说说字符集和编码 快下班时,爱问问题的小朋友Nico又问了一个问题: "sqlserver里面有char和nchar,那 ...

  6. Ansi,UTF8,Unicode,ASCII编码的区别

    近日需要不同的编码,关于上述编码,一直迷迷糊糊,查了些资料,总算大致了解了, 下面全是从网上搜来的: 1.  ASCII和Ansi编码     字符内码(charcter code)指的是用来代表字符 ...

  7. ANSI, UTF-8, Unicode, GBK, GB2312 字符编码小结

    这两天碰见一个Bug,涉及到字符编码,索性研究了下,整理出来,以便今后查阅. ASCII码,0~127,128个,这个就不用多说了,他是计算机文明的基石.但是这里面只有英文字母,其他国家如何把本国的文 ...

  8. 【字符编码】 简洁理解ANSI,UTF8,Unicode,ASCII编码的差别

    目录 简略 说明 1.  ASCII和ANSI编码 2. UNICODE 4.  UTF-8 参考 简略 ASCII             1个字节=1个文字 ANSI                ...

  9. 在linux上ansi格式转换换utf-8格式会乱码吗?,c++对编码格式ANSI utf8 unicode 进行转换...

    Windows下有不少种编码格式,在与别的系统环境中有文件传输或通讯时,这些编码就很重要.linux 好比在windows中换行是\r\n 在linux或mac下是\n,若是不对编码进行转换就会出现乱 ...

最新文章

  1. python 输入文件名查找_Python实现的根据文件名查找数据文件功能示例
  2. 为什么工厂老板们从不「迷信」人工智能?
  3. mysql数据库有几种连接方法_几种常见的数据库连接方法
  4. 电脑退出全屏按哪个键_电脑键盘上的F1到F12,每一个都是快捷键大家都会用到...
  5. bugku_本地包含
  6. java -web html5学习1
  7. ElasticSearch和mysql对比
  8. 一个撕心裂肺的爱情故事
  9. KTable的设置单元格属性
  10. paip.c++ qt creator svn 设置以及使用总结.
  11. oc实时渲染的图如何导出_最新C4D渲染器全家桶随便用,不仅有OC+阿诺德,还有两款哦...
  12. 普华永道-开放数据资产估值白皮书,首创“数据势能”估值模型
  13. R语言入门代码(二)for循环的理解
  14. 3.DesignForVias\1.AutoRoutingFirstSetp
  15. FCBF算法的Matlab实现
  16. 计算机counta函数怎么用,counta函数的使用方法及实例 看完你就知道了
  17. CSS【进阶】线性径向渐变background-image:linear-gradient();background-image:radial-gradient();
  18. 类似帝国时代的java游戏_有哪些类似《帝国时代》系列的好游戏推荐?
  19. 三菱PLC以太网模块FX3U-ENET-L的使用方法
  20. aqr资本二十年精选二十篇_2016年3月:前10名和编辑精选

热门文章

  1. Serializing - 序列化 综述 – To be continued.
  2. maven自定义本地仓库目录
  3. 在 .NET Framework Data Provider for Microsoft SQL Server Compact 3.5 中发生错误
  4. 一种基于memcache或redis缓存架构的验证码
  5. android Launcher——数据加载与变更
  6. mysql学习【第2篇】:基本操作和存储引擎
  7. 分布式系统最终一致性
  8. 人工智能+人=强大的网络安全
  9. ShutIt:一个基于Python的shell自动化框架
  10. java反射 一些理解