Ansi,UTF8,Unicode编码(续)   
               添加时间:2013-6-4 点击量: 
 
              1.三种编码的回顾
Ansi字符串我们最熟悉,英文占一个字节,汉字2个字节,以一个\0结尾,常用于txt文本文件。 
Unicode字符串,每个字符(汉字、英文字母)都占2个字节;在VC++的世界里,Microsoft斗劲激劝应用Unicode,如wchar_t。 
UTF8是Unicode一种紧缩情势,英文A在unicode中默示为0 x0041,英语中这种存储体式格式太浪费,因为浪费了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(sLensizeof(wchar_t));
    MultiByteToWideChar(CP_ACP, NULL, sAnsi, -1, sUnicode, sLen); 
    ofstream rtxt(ansitouni.txt);
    rtxt.write(\xff\xfe,2);//原因拜见上一篇——小尾字节序体式格式存储
    rtxt.write((char)sUnicode, sLensizeof(wchar_t));
    rtxt.close();
    [] sUnicode; 
    sUnicode =NULL; 
    //free(sUnicode);
}
Unicode转ANSI
void UnicodeToAnsi() 
{
    wchar_t sUnicode = LConvert 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();
    [] sAnsi; 
    sAnsi =NULL; 
    //free(sAnsi);
}
Unicode转UTF8
void UnicodeToUtf8()
{
    wchar_t sUnicode = LConvert 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();
    [] 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, sLensizeof(wchar_t));
    rtxt.close();
    [] 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); 
    [] 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();
    [] changeResult;
    [] changeTemp;
}
题目记录: 
关于字符串的长度a.String类型的length()和size()函数都返回字符串的真实大小,不包含\0‘ ; 
b.char类型的strlen()函数也是返回字符串的真实大小,不包含\0‘ ; 
c.重视,sizeof()函数包含\0‘ ,如char str[] = “Hello” ;则sizeof (str ) = 6。
彼此相爱,却不要让爱成了束缚:不如让它成为涌动的大海,两岸乃是你们的灵魂。互斟满杯,却不要同饮一杯。相赠面包,却不要共食一个。一起歌舞欢喜,却依然各自独立,相互交心,却不是让对方收藏。因为唯有生命之手,方能收容你们的心。站在一起却不要过于靠近。—— 纪伯伦《先知》
                     
                  
     
  
 
    
    
1.三种编码的回顾
Ansi字符串我们最熟悉,英文占一个字节,汉字2个字节,以一个\0结尾,常用于txt文本文件。 
Unicode字符串,每个字符(汉字、英文字母)都占2个字节;在VC++的世界里,Microsoft斗劲激劝应用Unicode,如wchar_t。 
UTF8是Unicode一种紧缩情势,英文A在unicode中默示为0 x0041,英语中这种存储体式格式太浪费,因为浪费了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(sLensizeof(wchar_t));
MultiByteToWideChar(CP_ACP, NULL, sAnsi, -1, sUnicode, sLen);
ofstream rtxt(ansitouni.txt);
rtxt.write(\xff\xfe,2);//原因拜见上一篇——小尾字节序体式格式存储
rtxt.write((char)sUnicode, sLensizeof(wchar_t));
rtxt.close();
[] sUnicode;
sUnicode =NULL;
//free(sUnicode);
}
Unicode转ANSI
void UnicodeToAnsi()
{
wchar_t sUnicode = LConvert 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();
[] sAnsi;
sAnsi =NULL;
//free(sAnsi);
}
Unicode转UTF8
void UnicodeToUtf8()
{
wchar_t sUnicode = LConvert 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();
[] 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, sLensizeof(wchar_t));
rtxt.close();
[] 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);
[] 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();
[] changeResult;
[] changeTemp;
}
题目记录: 
关于字符串的长度a.String类型的length()和size()函数都返回字符串的真实大小,不包含\0‘ ; 
b.char类型的strlen()函数也是返回字符串的真实大小,不包含\0‘ ; 
c.重视,sizeof()函数包含\0‘ ,如char str[] = “Hello” ;则sizeof (str ) = 6。




