1 . VC8(VS2005)
VC8能识别的源文件编码有三种:ANSI(本地codepage),utf8,utf16. 后面两种要保留BOM,否则VC8不能识别。
基本上源文件的编码其实只对文件中的字符串的值有影响。
先说结论:
对于普通字符串("中文1234"),VC8会把它从源文件的编码格式转为ANSI字符串。
对于宽字符串(L"中文1234"), VC8会把它从源文件的编码格式转为utf16字符串。
例子1:test.cpp (编码是utf8)
如果这个程序在codepage 936(简体中文)上面去compile
输出的结果就是
中文1234
0xd6 0xd0 0xce 0xc4 0x31 0x32 0x33 0x34
可以看出是gb2312的编码,而不是utf8
如果这个程序在codepage 932(日文)上面去compile
输出的结果就是
中文1234
0x92 0x86 0x95 0xb6 0x31 0x32 0x33 0x34
可以看出是shift-jis的编码,也不是utf8
(注:shift-jis也包含"中文"两个字)
也就是说 同样的source code在不同的code page下产生不同的可执行文件
例子2:test.cpp (编码改为ANSI)
如果这个程序在codepage 936(简体中文)上面去compile
输出的结果就是
中文1234
0xd6 0xd0 0xce 0xc4 0x31 0x32 0x33 0x34
可以看出是gb2312的编码,而不是utf8
把相同的file拷贝到codepage 932(日文)上面去compile
输出的结果是
ヨミホト1234
0xd6 0xd0 0xce 0xc4 0x31 0x32 0x33 0x34
可以看出是binary内容相同,但是string却不同了
例子三:test.cpp (编码utf8)
在任何平台下使用vc8去compile,结果都应该是输出
0x2d 0x4e 0x87 0x65 0x31 0x0 0x32 0x0 0x33 0x0 0x34 0x0 0x0 0x0
顺便考你一下:
如果想输出"中文1234"的utf8格式,应该如何写代码,保证vc8在任何语言平台下面去compile,结果都一样正确?
2. gcc/g++
gcc/g++似乎不支持utf16编码的源文件
可以处理ANSI和utf8格式的源文件(no BOM)
如果采用例子一所用的源文件(utf8编码)
会输出
0xe4 0xb8 0xad 0xe6 0x96 0x87 0x31 0x32 0x33 0x34
可以看出是utf8是编码
这一点上看vc8和gcc是不同的
如果采用例子三所用的源文件(编码是utf8,使用L和wchar_t)
会输出
0x2d 0x4e 0x0 0x0 0x87 0x65 0x0 0x0 0x31 0x0 0x0 0x0 0x32 0x0 0x0 0x0 0x33 0x0 0x0 0x0 0x34 0x0 0x0 0x0 0x0 0x0 0x0 0x0
可以看出gcc的wchar_t是四个字节,跟vc8也不同
有些复杂,希望不要让你困扰。
VC8能识别的源文件编码有三种:ANSI(本地codepage),utf8,utf16. 后面两种要保留BOM,否则VC8不能识别。
基本上源文件的编码其实只对文件中的字符串的值有影响。
先说结论:
对于普通字符串("中文1234"),VC8会把它从源文件的编码格式转为ANSI字符串。
对于宽字符串(L"中文1234"), VC8会把它从源文件的编码格式转为utf16字符串。
例子1:test.cpp (编码是utf8)
#include
<
stdio.h
>
#include < string .h >
#define TEST_MSG "中文1234"
int main( int argc, char * argv[])
{
char buf[ 1024 ] = { 0 };
strcpy(buf,TEST_MSG);
printf("%s\n",buf);
for ( int i = 0 ;buf[i] != 0 ; ++ i)
{
printf( " 0x%2x " ,(unsigned char )buf[i]);
}
return 0 ;
}
#include < string .h >
#define TEST_MSG "中文1234"
int main( int argc, char * argv[])
{
char buf[ 1024 ] = { 0 };
strcpy(buf,TEST_MSG);
printf("%s\n",buf);
for ( int i = 0 ;buf[i] != 0 ; ++ i)
{
printf( " 0x%2x " ,(unsigned char )buf[i]);
}
return 0 ;
}
如果这个程序在codepage 936(简体中文)上面去compile
输出的结果就是
中文1234
0xd6 0xd0 0xce 0xc4 0x31 0x32 0x33 0x34
可以看出是gb2312的编码,而不是utf8
如果这个程序在codepage 932(日文)上面去compile
输出的结果就是
中文1234
0x92 0x86 0x95 0xb6 0x31 0x32 0x33 0x34
可以看出是shift-jis的编码,也不是utf8
(注:shift-jis也包含"中文"两个字)
也就是说 同样的source code在不同的code page下产生不同的可执行文件
例子2:test.cpp (编码改为ANSI)
如果这个程序在codepage 936(简体中文)上面去compile
输出的结果就是
中文1234
0xd6 0xd0 0xce 0xc4 0x31 0x32 0x33 0x34
可以看出是gb2312的编码,而不是utf8
把相同的file拷贝到codepage 932(日文)上面去compile
输出的结果是
ヨミホト1234
0xd6 0xd0 0xce 0xc4 0x31 0x32 0x33 0x34
可以看出是binary内容相同,但是string却不同了
例子三:test.cpp (编码utf8)
#include
<
stdio.h
>
#include < string .h >
#define TEST_MSG L"中文1234"
int main( int argc, char * argv[])
{
char buf[ 1024 ] = { 0 };
memcpy(buf,( const char * )TEST_MSG, sizeof (TEST_MSG));
// printf("%s\n",buf);
for ( int i = 0 ;i < sizeof (TEST_MSG); ++ i)
{
printf( " 0x%x " ,(unsigned char )buf[i]);
}
return 0 ;
}
#include < string .h >
#define TEST_MSG L"中文1234"
int main( int argc, char * argv[])
{
char buf[ 1024 ] = { 0 };
memcpy(buf,( const char * )TEST_MSG, sizeof (TEST_MSG));
// printf("%s\n",buf);
for ( int i = 0 ;i < sizeof (TEST_MSG); ++ i)
{
printf( " 0x%x " ,(unsigned char )buf[i]);
}
return 0 ;
}
在任何平台下使用vc8去compile,结果都应该是输出
0x2d 0x4e 0x87 0x65 0x31 0x0 0x32 0x0 0x33 0x0 0x34 0x0 0x0 0x0
顺便考你一下:
如果想输出"中文1234"的utf8格式,应该如何写代码,保证vc8在任何语言平台下面去compile,结果都一样正确?
2. gcc/g++
gcc/g++似乎不支持utf16编码的源文件
可以处理ANSI和utf8格式的源文件(no BOM)
如果采用例子一所用的源文件(utf8编码)
会输出
0xe4 0xb8 0xad 0xe6 0x96 0x87 0x31 0x32 0x33 0x34
可以看出是utf8是编码
这一点上看vc8和gcc是不同的
如果采用例子三所用的源文件(编码是utf8,使用L和wchar_t)
会输出
0x2d 0x4e 0x0 0x0 0x87 0x65 0x0 0x0 0x31 0x0 0x0 0x0 0x32 0x0 0x0 0x0 0x33 0x0 0x0 0x0 0x34 0x0 0x0 0x0 0x0 0x0 0x0 0x0
可以看出gcc的wchar_t是四个字节,跟vc8也不同
有些复杂,希望不要让你困扰。