如何判断一个txt文件采用的编码方式?

iamluda 2008-06-03 05:08:18
用windows的记事本编写的txt文件,保存后有4中编码格式
1. ANSI 2. unicode 3. unicode big endian 4. UTF-8

如何才能判断一个txt文件采用的编码方式?

对我的应用来说,我的程序仅仅能识别 ANSI编码方式,我该如何转换其他编码方式的文件到ANSI?
...全文
18678 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
iamluda 2008-06-11
  • 打赏
  • 举报
回复
UNICODE 编码的格式,表示一个字符要两个字节表示一个字符。汉字和英文的占用字节数相同。
utf8 编码的格式,表示一个字符需要的字节是不固定的.
由于文件比较大,因此要分段读取,然后进行转换,对于utf8 这样编码格式的文件,缓冲区该如何处理呢?

代码如下:
CStdioFile myFile;
unsigned char p_buf;////先读的字节

Cstring temp_str;//转换后的字符串

#define BUF_SIZE 2048
unsigned char buf[BUF_SIZE];//要转换的数据
unsigned char buf_out[BUF_SIZE];//转换后的数据

//先读上2个字节
myFile.Read(&p_buf,1);
int p = p_buf * 256;
myFile.Read(&p_buf,1);
p = p_buf + p;
//文件读指针回到首位
myFile.Seek(0, CFile::begin);

int n=1;//实际读取的字节数

switch(p)
{
case 0xefbb: //"UTF-8"
//对于UTF-8该如何处理??

break;
case 0xfffe: // unicode小端格式
while(n)
{
n=fread(buf, 1, BUF_SIZE, pFile);
u2s(buf,n,buf_out);
temp_str += buf;
memset(buf,0,BUF_SIZE);
memset(buf,0,BUF_SIZE);
}
break;
case 0xfeff: //"Unicode big endian"
//处理方法同上面
break;
default: //ANSI
break;
}


对于utf8 这样编码格式的文件,缓冲区该如何处理呢?

用户 昵称 2008-06-03
  • 打赏
  • 举报
回复
先读前几个字节,判断编码,然后再读后面的,API转换。

//UNICODE little endian
char *
u2s( unsigned char *buf, unsigned short length, char *tmpbuf )
{
int i;
char *p;
char s[ 10 ] = "";
wchar_t wstr[ 1 ];
CString mstr;
int l, curlen;

*tmpbuf = 0;
curlen = 0;
mstr = _T( "" );

for( i = 0; i < ( int )length; i += 2 )
{
p = ( char * )wstr;
*p = *( buf + 1 ); //high
*( p + 1 ) = *buf; //low
mstr = wstr;
memset( s, 0, sizeof( s ) );
strcat( s, ( const char * )mstr );
if( *buf ) //if low is not 0
{
s[ 2 ] = 0;
l = 2;
}
else
{
s[ 1 ] = 0;
l = 1;
}

strcat( tmpbuf + curlen, ( const char * )s );
curlen += l;

buf += 2;
}

return tmpbuf;
}

//unicode big endian
char *
unicode2s( unsigned char *buf, unsigned short length, char *tmpbuf )
{
int i;
char *p;
char s[ 10 ] = "";
wchar_t wstr[ 1 ];
CString mstr;
int l, curlen;

*tmpbuf = 0;
curlen = 0;
mstr = _T( "" );

for( i = 0; i < ( int )length; i += 2 )
{
p = ( char * )wstr;
*p = *( buf ); //high
*( p + 1 ) = *( buf + 1 ); //low
mstr = wstr;
memset( s, 0, sizeof( s ) );
strcat( s, ( const char * )mstr );
if( *( buf + 1 ) ) //if low is not 0
{
s[ 2 ] = 0;
l = 2;
}
else
{
s[ 1 ] = 0;
l = 1;
}

strcat( tmpbuf + curlen, ( const char * )s );
curlen += l;

buf += 2;
}

return tmpbuf;
}

//utf8 convert to gb
char *
utf82ascii( unsigned char *utf8, unsigned short length, char *buf )
{
int i = 0;
unsigned short a;
unsigned char b;
char *p = buf;
unsigned char t[ 2 ];


do
{
if( 0xe0 == ( *utf8 & 0xf0 ) &&
0x80 == ( *( utf8 + 1 ) & 0xc0 ) &&
0x80 == ( *( utf8 + 2 ) & 0xc0 ) )
{
//3个字节
b = *utf8;
b &= 0x0f;
a = b;

a <<= 6;
b = *( utf8 + 1 );
b &= 0x3f;
a |= b;

a <<= 6;
b = *( utf8 + 2 );
b &= 0x3f;
a |= b;

t[ 0 ] = ( a >> 8 ) & 0xff;
t[ 1 ] = ( a & 0xff );
u2s( t, 2, p );

p += 2;

i += 3;
utf8 += 3;
}
else if ( 0xc0 == ( *utf8 & 0xe0 ) &&
0x80 == ( *( utf8 + 1 ) & 0xc0 ) )
{
//2个字节
b = *utf8;
b &= 0x1f;
a = b;

a <<= 6;
b = *( utf8 + 1 );
b &= 0x3f;
a |= b;

t[ 0 ] = ( a >> 8 ) & 0xff;
t[ 1 ] = ( a & 0xff );
u2s( t, 2, p );

p += 2;

i += 2;
utf8 += 2;
}
else
{
//1个字节
*( p++ ) = *( utf8++ );

i++;
}
} while ( i < length );
*p = 0;

return buf;
}
greatws 2008-06-03
  • 打赏
  • 举报
回复
UTF8 to unicode
http://topic.csdn.net/u/20080514/18/c6ad1ab7-24e8-40a3-a9f9-0a9f712e3df1.html

ansi to utf8
http://topic.csdn.net/u/20080508/17/e2ce8c52-b27a-4b56-b7bb-439373f0c214.html

参考下就差不多了
greatws 2008-06-03
  • 打赏
  • 举报
回复
对,cnzdgs说的没错,有高低位互换的问题。

不过还有无BOM的文本文件,就要根据字符来判断了
参考http://topic.csdn.net/u/20080518/13/4192c3b5-52e4-442d-962a-1f17293ba50e.html
ouyh12345 2008-06-03
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 cnzdgs 的回复:]
LS写反了吧?应该是0xbbef、0xfeff、oxfffe。
用MultiByteToWideChar先转成Unicode,再用WideCharToMultiByte转成多字节。
[/Quote]

源码里还有一些处理
goodwinds 2008-06-03
  • 打赏
  • 举报
回复
记事本保存文件时,在开头加入几个字节,来判断字符集或编码
开头字节 Charset/encoding
FF FE unicode
FE FF unicode big endian
EF BB 8F UTF8
你可以保存不同的编码方式,用UltraEdit打开查看二进制。

你的程序读出文件,判断前面几个字节就可以了

用WideCharToMultiByte进行不同字符编码的转换。
cnzdgs 2008-06-03
  • 打赏
  • 举报
回复
LS写反了吧?应该是0xbbef、0xfeff、oxfffe。
用MultiByteToWideChar先转成Unicode,再用WideCharToMultiByte转成多字节。
ouyh12345 2008-06-03
  • 打赏
  • 举报
回复
google 记事本 编码格式

有个例子可以参考一下:
如何判断文本文件的编码格式?

主要代码:
case 0xefbb:
code="UTF-8";
break;
case 0xfffe:
code="Unicode";
break;
case 0xfeff:
code="Unicode big endian";
break;
default:
code="ANSI";

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧