小明思考

高性能服务器端计算
posts - 70, comments - 428, trackbacks - 0, articles - 0
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

C++源文件编码问题

Posted on 2007-04-05 15:30 小明 阅读(5344) 评论(6)  编辑 收藏 引用 所属分类: C/C++ToolsG11N/ICU
1 . VC8(VS2005)

   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;
}

如果这个程序在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;
}

在任何平台下使用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也不同


有些复杂,希望不要让你困扰。

Feedback

# re: C++源文件编码问题  回复  更多评论   

2007-04-05 19:36 by Corner Zhang
建议把源代码的文件的编码设为UTF8

# re: C++源文件编码问题  回复  更多评论   

2007-04-05 22:03 by 自大者
我看楼主自己也没搞清什么是"字符集"和"字符集编码", 根本就不是什么utf16, 而是utf16-be, 就是ucs2, 就是你所谓的unicode.

# re: C++源文件编码问题  回复  更多评论   

2007-04-05 23:31 by 阿来
长见识了 :)

# re: C++源文件编码问题  回复  更多评论   

2007-09-26 09:11 by Minidx全文检索
“任何平台下使用vc8去compile,结果都应该是……“
VC8还支持什么平台??

# re: C++源文件编码问题  回复  更多评论   

2008-03-07 00:27 by 逍遥剑客
头疼, 以后全UTF吧

# re: C++源文件编码问题  回复  更多评论   

2011-12-09 10:11 by NetAsker
建议初学者别看这个。会被误导的。
这个例子只会让初学者更糊涂。
不知道是作者不理解unicode,还是故意搅混水。。
1。 首先,第一个例子,“如果这个程序在codepage 932(日文)上面去compile” 那么,你是拷贝过去的还是在日本系统上自己编辑的?从结果来看,我觉得你是拷贝过去的。

2。在看你的例3 test 中为什么没有字符串打印? 你注视掉 //printf("%s\n",buf);这么关键的一句,为什么呢??你可以用wcsprintf测试。

3。还是测试3, “在任何平台下使用vc8去compile,结果都应该是输出
0x2d 0x4e 0x87 0x65 0x31 0x0 0x32 0x0 0x33 0x0 0x34 0x0 0x0 0x0”

你知道这是什么编码格式吗?utf-8还是utf16?,你说任何平台下使用vc8,你说的任何平台什么意思?





只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理