C++ wftream该如何使用?

天堂里的死神 2007-02-01 08:59:14
用C++写的DLL,第一想法就是用fstream而不是fopen,由于我的DLL内部参数传递的时候,所有一切都是使用Unicode编码,所以自然使用的是使用wfstream了。
读文件正常,但是,下面发生的一切就开始很诡异了:
当我使用get从文件中读取内容到一个wchar_t数组后,发现……
英文是对的,因为Unicode的英文是ASCII前面加00
中文错了,比如“中”0x4e2d,变成了0x004e 0x002d……

希望大家能帮帮我,谢谢……
...全文
454 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
天堂里的死神 2007-02-02
  • 打赏
  • 举报
回复
嗯,多谢wingfiring,确实,C++的locale对于读钱能那本噩梦书入门的人会很郁闷,技术到用时方觉得悔恨,唉……好在还有时间,慢慢做吧……

PS 您说的那本书可能是 标准C++输入输出流与本地化 吧?我看过了,这本书其他都还行,就是关于编码方面介绍得太少,例程也不多。不过没关系,我会继续努力的,有资料要做,没有资料创造资料也要做,呵呵。

就此结贴,v2002750、HewpKanXue,多谢你们setlocale的提醒,让我基本上明白了自己的方向应该放在std::locale上。htqx您的回复让我避免作了很多无用功,谢谢你。wingfiring,也很感谢您的回复,它们对我很有用。

谢谢大家!
wingfiring 2007-02-02
  • 打赏
  • 举报
回复
关于这部分,可以参考C++标准文档,msdn和google的结果大多不准确或者语焉不详.结合stl的源代码来分析.
关于locale的内容其实相当多和复杂,但是专门的书很少.据说有一本专门讲述这一内容书,可是我没看过.
wingfiring 2007-02-02
  • 打赏
  • 举报
回复
setlocale(LC_ALL, "");是不行的。
每个stream对象都有自己的locale处理,这是stream构造时就产生的。如果没有为stream特别指定locale,stream就会持有一个locale::global( loc )的副本。因此,一旦你的stream已经创建了,那么,你在指定全局的locale也没有效果了。
另外,setlocale是c的函数部分,对于C++标准库中的stream,如果是偶尔改变某个stream的locale,可以通过stream.imbue方法修改,如果需要全局效果,可以通过locale::global。
有一点,在locale::global被调用之前创建的stream不会受到影响,也就是说cin,cout,wcin等等的locale是不会受到locale::global和setlocale的影响的。这些stream对象只能是通过stream.imbue来修改其locale.
天堂里的死神 2007-02-02
  • 打赏
  • 举报
回复
您好HewpKanXue(),谢谢您的回复 ^_^
我的初衷实际上是想放弃C风格化函数,转而使用C++风格的函数,因此主要就往fstream的方向去想了。必须承认,我对stream和C++ locale 的理解很有限,还需要继续学习……
上班了,今天中午来结这个贴 ^_^
wingfiring 2007-02-01
  • 打赏
  • 举报
回复
在创建wfstream wfs;之前,
locale loc ("chs");//改成你的文件对应的编码,要查文档。
locale old = locale::global( loc );
然后再开始你的所有操作,
最后,再把old恢复回去。
天堂里的死神 2007-02-01
  • 打赏
  • 举报
回复
中文locale的代码页是多少?
HewpKanXue 2007-02-01
  • 打赏
  • 举报
回复
要设置这个
setlocale(LC_ALL, "");
文件打开也要_wopen 最好用宏_wfopen_s
字符读用getwc
应该可以了
天堂里的死神 2007-02-01
  • 打赏
  • 举报
回复
谢谢,但是还是不行……
v2002750 2007-02-01
  • 打赏
  • 举报
回复
wfstream wfs;
wfs.open(L"UTF16.bin");
setlocale(LC_ALL,"chinese");
.............
v2002750 2007-02-01
  • 打赏
  • 举报
回复
加上这句看看:
setlocale(LC_ALL,"chinese");
天堂里的死神 2007-02-01
  • 打赏
  • 举报
回复
todototry() :
你用的是Linux吗?
在Vc下似乎没有这个函数?
天堂里的死神 2007-02-01
  • 打赏
  • 举报
回复
-_-b sorry,
问了这么个不该问的问题……
todototry 2007-02-01
  • 打赏
  • 举报
回复
wget()
天堂里的死神 2007-02-01
  • 打赏
  • 举报
回复
参考代码如下,创建一个文本并存储成Unicode格式就可以了:
// 读取UTF16试验
// 过程:读取一个已知以UTF16存储的文件
wfstream wfs;
wfs.open(L"UTF16.bin");
if( wfs.is_open() )
{
wstring wstr;
getline( wfs, wstr);

// 读出来的结果是不对的!文件的内容,比如:0xfffe 0x2d4e 0x8765
// 读出来后成为了:0x00ff , 0x00fe,0x002d,0x004e,0x0087,0x0065
::MessageBoxW(NULL, wstr.c_str(), L"UTF16 wfstream", MB_OK);

wfs.close();
}
天堂里的死神 2007-02-01
  • 打赏
  • 举报
回复
比较急,大家有做过的希望能帮帮忙啊……
chinesealbert 2007-02-01
  • 打赏
  • 举报
回复
mark
天堂里的死神 2007-02-01
  • 打赏
  • 举报
回复
htqx:您好,多谢你的回复,我明白了很多。
w开始的实际上不是读写unicode,而是将内码转化为unicode内部表示.也就是外部接口支持的是内码,但是内部表示是unicode,中间的转换就是他们和非w开始的差别

这个中间的内码和外部接口是什么意思?
htqx 2007-02-01
  • 打赏
  • 举报
回复

以前的研究结果(vc) :
1. c++所有的io类都不支持unicode读写操作,包括w开始的
2. w开始的实际上不是读写unicode,而是将内码转化为unicode内部表示.也就是外部接口支持的是内码,但是内部表示是unicode,中间的转换就是他们和非w开始的差别
3. 如果要自己写读写unicode, 那么个人觉得比较容易的方法,就是用不转化的非w开始来读取数据,然后转化为wchar_t数组,因为本身就是unicode,所以这个只是将两个char直接合并成一个wchar_t,相当简便(如果是utf-8编码,也不会很复杂)
4. txt文本有个前导标志 : ff fe 之类的,应该跳过

OOPhaisky 2007-02-01
  • 打赏
  • 举报
回复
mark
czp_opensource 2007-02-01
  • 打赏
  • 举报
回复
mark

64,651

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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