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也不同
有些復雜,希望不要讓你困擾。