2011-10-01 125 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 

這僅實現了流緩衝界面的最低限度。如果需要,可以添加緩衝區管理代碼以提高性能。