开发者

How to convert a std::istream to std::wistream

开发者 https://www.devze.com 2023-04-10 15:24 出处:网络
I have an istream and some code expects a wistream. I literally want every char of a source stream zero extended to a wchar_t.I don\'t care about code pages, I don\'t care about local开发者_如何学运维

I have an istream and some code expects a wistream.

I literally want every char of a source stream zero extended to a wchar_t. I don't care about code pages, I don't care about local开发者_如何学运维ization, I simply want to seamlessly pipe this input, what's the fastest way to do it?


You can write a read buffer to adapt the underlying stream buffer in the istream to your wistream:

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

Later:

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

// now work with wistream

This implements only the bare minimum of streambuf's interface. You could add buffer management code to improve performance if you need to.


I think it is not possible without writing a complicated* wrapper around an std::wistream to provide an std::istream interface. The difference between the two is the char type used when instantiating these classes from templates, thus making std::istream (char_type = char) and std::wistream (char_type = wchar_t) in two different class hierarchies. They only share std::ios_base as a common base class, which does not provide something useful for your current problem.

Because of that, the following piece of code will not compile (it tries to replace the internal std::streambuf of s2 with s1's one, thus making I/O operations on s2 performing on the data from the file) :

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 :(

I'm not aware of a simple solution, perhaps a Boost IOStreams Filter can be used (I never tried :( ).

If you're not dealing with binary data, and your stream length isn't too big, try reading all the data to a string and then convert (zero extend as you say) into an std::wistringstream.

* : complicated means that you have reasonable knowledge about std::streams. I confess I'm not comfortable with streams.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号