2011-10-01 75 views
1

我有一个istream,一些代码需要一个wistream。如何将std :: istream转换为std :: wistream

我真的希望将源码流的每个字符都扩展为wchar_t。我不关心代码页,我不关心本地化,我只是想无缝地输入这个输入,最快的方法是什么?

回答

0

我认为这是不可能的,如果没有写一个复杂*包装围绕std::wistream提供一个std::istream接口。两者之间的差异是从模板实例化这些类时使用的字符类型,因此在两个不同的类层次结构中使std::istream(char_type = char)和std::wistream(char_type = wchar_t)。他们只共享std::ios_base作为一个通用的基类,它不提供对你目前的问题有用的东西。

由于这个原因,下面的代码段不会编译(它试图与S1的一个替换的s2的内部std::streambuf,从而使上S2从文件对所述数据I/O操作):

std::wifstream  s1 ; 
std::istringstream s2 ; 

// assuming s1 and s2 are correctly initialized ... 

s2.ios::rdbuf(s1.rdbuf()) ; // will not compile, unfortunately, unless the char type 
          // is the same for the two streams :(

我不知道一个简单的解决方案,也许Boost IOStreams Filter都可以使用(我从来没有试过:()。

如果你不处理二进制数据,以及您的流长度是不是太大,尝试读取所有数据到一个字符串,然后转换(零延伸为你唉)变成std::wistringstream

*:复杂表示您有合理有关std :: streams的知识。我承认我不喜欢流媒体。

+0

如果你不得不写一个适应性的rdbuf并不困难... – bdonlan

+0

我从来没有说过这是不可能的,但我讨厌在std :: streambuf的深层细节中挖掘......(我编辑了我的文章为了清晰起见) – overcoder

+0

我认为你们两个都是对的,但似乎可能,但挖掘STL流类的内部本身就是一场噩梦。最后,我将代码改为使用函子的boost函数来完成所需的转换。 – clemahieu

1

你可以写一个读缓冲区在istream底层流缓冲适应你wistream

class adapting_wistreambuf : public wstreambuf { 
    streambuf *parent; 
public: 
    adapting_istreambuf(streambuf *parent_) : parent(parent_) { } 
    int_type underflow() { 
    return (int_type)parent->snextc(); 
    } 
}; 

后来:

istream &somestream = ...; 
adapting_wistreambuf sb(somestream.rdbuf()); 
wistream wistream(&sb); 

// now work with wistream 

这仅实现了流缓冲界面的最低限度。如果需要,可以添加缓冲区管理代码以提高性能。