如何将std :: istream转换为std :: wistream

时间:2011-10-01 22:35:37

标签: c++ unicode stream ascii

我有一个istream,一些代码需要一个wistream。

我确实希望源流的每个char都扩展为wchar_t。我不关心代码页,我不关心本地化,我只是想无缝地管道这个输入,有什么最快的方法呢?

2 个答案:

答案 0 :(得分: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

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

答案 1 :(得分:0)

我认为如果不在std::wistream周围编写复杂*包装来提供std::istream接口,就不可能。两者之间的区别是从模板实例化这些类时使用的char类型,从而使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的合理的知识。我承认我对溪流感到不舒服。