最近遇到读取不同格式文件,由于C++不是原生支持unicode,读取起来比较麻烦。这篇博客详细介绍了不同编码格式的区别。
常见的类型有:ANSI,utf-8无bom格式,utf-8,usc2 little end,usc2 big end。其中utf8是unicode的一种最常见的实现方式。windows中的宽字符串支持:USC-2 Little End。BOM: Byte Order Mark。UTF-8 BOM又叫UTF-8 签名,其实UTF-8 的BOM对UFT-8没有作用,是为了支援UTF-16,UTF-32才加上的BOM,BOM签名的意思就是告诉编辑器当前文件采用何种编码,方便编辑器识别,但是BOM虽然在编辑器中不显示,但是用cout直接输出的时候会产生一串乱码,在Notepad++中打开可以看到黑色的0xff等字节。因此要跳过头三个字节。
windows下的wchar_t读取的就是UCS2 Little End,通常说的Unicode编码指的是UCS-2 little endian格式编码方式,即直接用两个字节存入字符的Unicode码。windows中C++有3种字符类型,char, wchar_t, TCHAR,最熟悉的char是单字节字符,适用于ANSI编码;wchar_t是双字节的宽字符类型,适用于unicode编码;TCHAR是一个宏,在ANSI坏境下定义为char,unicode坏境下定义为wchar_t。
#include
#include
#include
using namespace std;
enum FileType
{
ansi = 0,
unicode,
utf8
};
FileType GetFileType(ifstream& infile)
{
FileType type = ansi;
if (!infile) {
return ansi;
}
if (infile.good()){
char head[3];
infile.read(head,sizeof head);
//utf-8无bom格式无法通过开始字节区分
cout<<(head[0] & 0xff)<<" "<<(head[1] & 0xff)<<" "<<(head[2] & 0xff)<
//-----------------------------------------------
//创建不同格式的文件
//-----------------------------------------------
void CreateFileTest(FileType type,const char* filename)
{
ofstream out;
out.open(filename,ios::binary);
if (!out) {
return;
}
char head[3];
if (type == utf8) { //utf8有bom
head[0] = 0xef;
head[1] = 0xbb;
head[2] = 0xbf;
out.write(head,sizeof(head));
out<<"UTF-8"<
//-----------------------------------------------
//C++不同文件格式之间的转换
//-----------------------------------------------
#include
#include
//ANSI 转换成 unicode
bool ANSIToUnicode(const char* inStr,wchar_t* outDest,int MaxLen)
{
int len = 0;
if (MaxLen <= 0) {
return false;
}
len = ::MultiByteToWideChar(CP_ACP,0,inStr,-1,outDest,MaxLen);
if (len < 0) {
len = 0;
}
if (len < MaxLen) {
outDest[len] = 0;
} else {
outDest[MaxLen - 1] = 0;
return false;//溢出
}
return true;
}
//unicode转成utf-8无bom格式
bool UnicodeToUtf8(const wchar_t* inDest,char* outStr,int MaxLen)
{
int len = ::WideCharToMultiByte(CP_UTF8,0,inDest,-1,NULL,0,NULL,NULL);//获取长度
if (len > MaxLen) {
return false;
}
WideCharToMultiByte(CP_UTF8,0,inDest,-1,outStr,len,NULL,NULL);
outStr[len - 1] = 0;
return true;
}
//utf-8转换成unicode
bool Utf8ToUnicode(const char* inStr,wchar_t* outDest,int MaxLen)
{
int len = ::MultiByteToWideChar(CP_UTF8,0,inStr,-1,NULL,NULL);
if (len > MaxLen) {
return false;
}
::MultiByteToWideChar(CP_UTF8,0,inStr,-1,outDest,len);
outDest[len - 1] = 0;
return true;
}
bool UnicodeToANSI(const wchar_t* inStr,char* outDest,int MAxLen)
{
int len = ::WideCharToMultiByte(CP_ACP,0,inStr,-1,NULL,0,NULL,NULL);
if (len > MAxLen) {
return false;
}
::WideCharToMultiByte(CP_ACP,0,inStr,-1,outDest,len,NULL,NULL);
outDest[len - 1] = 0;
return true;
}
void testANSIUNICODE()
{
//把ansi转换成unicode
locale::global(locale("chs"));
wchar_t unicodebuf[1024];
memset(unicodebuf,0,sizeof(unicodebuf));
char* ansibuf = "这是一个字符串,任务是把字符串转换成不同格式";
cout<<"[ansi]:"<