主题:关于用C++标准库中的locale将汉字由multibytes转换到unicode的一个小问题
vc7.1中的一个问题
// 我用的是中文版的Windows2000 Professional locale langLocale("");
// 所以下面这行输出:Chinese_People's Republic of China.936 cout << langLocale.name() << endl;
char narrow[] = "你好hello";
// 下面这行输出:你好hello cout << narrow << endl;
wchar_t wide[100]; // 用这个Chinese_People's Republic of China.936的locale把 // "你好hello"变成宽字符的 use_facet<ctype<wchar_t> >(langLocale).widen(narrow, narrow + 9, wide); wide[strlen(narrow)] = L'\0';
// 输出是:hello 竟然没有你好两个字了,调试器观察,那两个字全是0xffff wcout << wide << endl;
怎么回事?库的错误?跟踪到函数_Dowiden,它又调用了_Mbrtowc 可是_Mbrtowc没有源码啊,显示源码在 f:\vs70builds\3077\vc\crtbld\crt\src\xmbtowc.c 靠!这路径好像是在开发visual studio哦 我的机子可没有f盘,想必是在微软某个家伙的机子上了。
怎么办?
回复人:freefalcon(心宇—小小菜鸟想高飞) 两星(中级) 信誉:100 2004-9-2 18:19:23 得分:5
|
回复人:plainsong(短歌) 两星(中级) 信誉:197 2004-9-2 18:23:22 得分:5
|
| C++缺省的local恐怕不支持GB码吧?对这部分不熟悉,不知道GB字符集的local名字是什么。
| | TOP |
回复人:CNXQS(天堂神曲(什么都不会,真无奈)) 二级(初级) 信誉:100 2004-9-2 21:22:16 得分:5
|
回复人:keiy() 一星(中级) 信誉:100 2004-9-2 22:05:26 得分:5
|
| 没用过vc7.1,一直用vc6.0,它的WideCharToMultiByte/MultiByteToWideChar 很好用
| | TOP |
回复人:shornmao(毛豆子[死猫]) 一星(中级) 信誉:120 2004-9-2 22:45:49 得分:5
|
| 字符集编码的转换,标准库只定义了接口,而没有提供实现,你需要自己提供
| | TOP |
回复人:rorot(我的猫儿) 一星(中级) 信誉:79 2004-9-3 0:29:29 得分:5
|
| try to use std::wcout.imbue( std::locale ( "ZHI" ) );
| | TOP |
回复人:iBear(大熊 不要怀疑我的温柔) 一级(初级) 信誉:100 2004-9-3 11:52:11 得分:5
|
| WideCharToMultiByte/MultiByteToWideChar 是win32的api,不是标准库里的东西
| | TOP |
回复人:goboo(高冉) 一级(初级) 信誉:100 2004-9-3 12:43:15 得分:5
|
回复人:rorot(我的猫儿) 一星(中级) 信誉:79 2004-9-3 21:51:23 得分:45
|
| 我的locale是zh_CN.GBK, 使用了你的ctype::widen(...)函数解析后查看了内存里是有内容的. 不过依然不能std::wcout << L"sdf地方"; ... 但是考虑到ctype::widen(...)转换的只是基本源字符里的96个标准字符, 所以我采用了codecvt<wchar_t, char, mbstate_t>::in(...)来转换.. 由于locale命名不标准, 我找不到在linux下的适当locale对象. 所以希望借助于win32的locale("ZHI")来测试...这里我贴的代码只是一个测试,不一定能解决你的问题, 希望楼主把解决的最终方案挂上来.
下面的代码希望有热心人在 VC7.0 下测试(不能使用VC6, DEV++), 把结果贴上来.... //------------------------------------ #include <iostream> #include <locale> #define DEBUG
int main( int argc, char** argv ) { char narrow[] = "China中国"; wchar_t *word = new wchar_t[100]; const char *from, *nstart = narrow; wchar_t *to = NULL, *wstart = word; mbstate_t cs; try { #ifdef WIN32 std::locale lang("ZHI"); #else std::locale lang("POSIX"); #endif std::use_facet< std::codecvt<wchar_t, char, mbstate_t> >(lang).in(cs, nstart, nstart+strlen(narrow), from, wstart, wstart+100, to );
#ifdef DEBUG std::wstring s(word); std::cout << "s.size(): " << s.size() << std::endl; const size_t size_ = s.size()*sizeof(wchar_t); char* ptr = (char*) word; for (int i=0; i<size_; ++i ) std::cout << static_cast <int> (*(ptr+i)) << " "; std::cout << std::endl; #endif std::wcout.imbue (lang); std::wcout << word << std::endl; delete[] word; } catch ( std::exception &e ) { std::cerr << e.what() << "\n"; } return 0; }
| | TOP |
回复人:duyanning(狗见愁) 一级(初级) 信誉:100 2004-9-4 22:07:51 得分:0
|
| #include <locale> #include <iostream>
using namespace std;
int main( ) { char narrow[] = "你好hello";
wchar_t wide[100]; memset(wide, 0, sizeof wide);
char* pszNext; wchar_t* pwszNext; mbstate_t state;
// locale loc("chs_china.936"); // 失败! // locale loc(""); // 还是失败!这和上面那行效果一样,我用的是中文简体w2k pro locale loc("C"); // 成功!竟然是这个默认的C locale
cout << loc.name() << endl;
use_facet<codecvt<wchar_t, char, mbstate_t> >(loc).in( state, narrow, narrow + strlen(narrow), pszNext, wide, wide + strlen(narrow), pwszNext );
wcout << wide << endl;
return EXIT_SUCCESS; }
-------------------------------- 我觉得还是不合适啊,竟然是这个C locale???大家再发表一下看法嘛
| | TOP |
回复人:rorot(我的猫儿) 一星(中级) 信誉:79 2004-9-4 22:53:16 得分:5
|
| "C"是US_ASCII的locale, 非国际化程序的默认方式. 你很幸运, 能在win32的支持下成功.
这里有专门介绍locale的内容 http://www.roguewave.com/support/docs/sourcepro/stdlibref/2-6.html 这里是一个multibytes2unicode使用facet的例子 http://www.roguewave.com/support/docs/sourcepro/stdlibug/40-5.html
| | TOP |
回复人:duyanning(狗见愁) 一级(初级) 信誉:100 2004-9-5 10:26:36 得分:0
|
| 用C locale,vc7.1搭配STLport-4.6.2也成功了;但是,若改用locale loc("CHS_CHN")会失败。"CHS_CHN"是在STLport-4.6.2\src\c_locale_win32\c_locale_win32.c中查到的。
| | TOP |
回复人:duyanning(狗见愁) 一级(初级) 信誉:100 2004-9-5 10:43:46 得分:0
|
| 但是,这不合适呀!如果"你好hello"即"\xc4\xe3\xba\xc3\x68\x65\x6c\x6c\x6f"是在保存在一个文件中的,那么上面这段程序在简体版的win2k和繁体版的win2k上运行势必有着不同的结果,而他们处理的却是完全一样的内容。
| | TOP |
回复人:yjh1982(血精灵) 一星(中级) 信誉:105 2004-9-20 15:24:09 得分:5
|
回复人:daylove(痴迷C++)(初级阶段-----在我没升四叉之前绝不灌水) 三级(初级) 信誉:100 2004-9-21 17:17:38 得分:5
|
该问题已经结贴 ,得分记录:freefalcon(5)、plainsong(5)、CNXQS(5)、keiy(5)、shornmao(5)、rorot(5)、iBear(5)、goboo(5)、rorot(45)、rorot(5)、yjh1982(5)、daylove(5)、
|