如何将istringstream和ifstream分配给istream变量?

时间:2016-08-05 21:42:11

标签: c++ ifstream istream istringstream

我希望有一个istream类型的变量,它可以保存文件或字符串的内容。我们的想法是,如果没有指定文件,则istream类型的变量将被赋予一个字符串。

std::ifstream file(this->_path)

std::istringstream iss(stringSomething);

std::istream is

我尝试将它们分配给istream变量,就像我从其他从同一基类继承的对象那样,但是没有用。

如何将istringstreamifstream分配给istream变量?

6 个答案:

答案 0 :(得分:5)

基类指针可以指向派生类数据。 std::istringstreamstd::ifstream都来自std::istream,因此我们可以这样做:

//Note that std::unique_ptr is better that raw pointers
std::unique_ptr<std::istream> stream;

//stream holds a file stream
stream = std::make_unique<std::ifstream>(std::ifstream{ this->_path });

//stream holds a string
stream = std::make_unique<std::istringstream>(std::istringstream{});

现在你只需要使用

提取内容
std::string s;
(*stream) >> s;

答案 1 :(得分:1)

从标准库中取出一个页面:不要分配值;分配参考。这可能是你想要的。

std::istringstream iss(stringSomething);
std::istream& input(iss);

因为流带有很多状态,所以复制它们充满了语义问题。例如,考虑在原始调用 seekg 之后, tellg 应该在副本中报告什么。相比之下,参考文献透明地回答了这个问题。

答案 2 :(得分:1)

在C ++中

std::istream is;

是一个实际的对象,分配给它将调用复制赋值运算符,该运算符将作为std :: istream的iss子对象复制到is和slice。 LogicStuff链接的示例将显示您需要为iss分配引用或指针,如下所示:

std::istream &is_ref = iss;

值,引用和指针之间的区别是C ++的基础,我建议你掌握them

答案 3 :(得分:1)

您无法分配到std::istream但您可以绑定到这样的引用:

#include <string>
#include <sstream>
#include <fstream>
#include <iostream>

std::istringstream test_data(R"~(

some test data here
instead of in an external
file.

)~");

int main(int, char* argv[])
{
    // if we have a parameter use it
    std::string filename = argv[1] ? argv[1] : "";

    std::ifstream ifs;

    // try to open a file if we have a filename
    if(!filename.empty())
        ifs.open(filename);

    // This will ONLY fail if we tried to open a file
    // because the filename was not empty    
    if(!ifs)
    {
        std::cerr << "Error opening file: " << filename << '\n';
        return EXIT_FAILURE;
    }

    // if we have an open file bind to it else bind to test_data
    std::istream& is = ifs.is_open() ? static_cast<std::istream&>(ifs) : test_data;

    // use is here
    for(std::string word; is >> word;)
    {
        std::reverse(word.begin(), word.end());
        std::cout << word << '\n';
    }
}

答案 4 :(得分:0)

在C ++中,即使Child继承自Parent,也无法将Child类型的对象分配给Parent类型的变量。但是,您可以将类型为Child的指针指定给类型 Parent 的指针。您可能需要考虑动态分配对象。

答案 5 :(得分:0)

std::istream可以是来自constructed std::streambuf(基本上是生成或使用字符的设备)。所有i/ostream个对象都有关联的std::streambuf,可以共享。

std::ifstream file(this->_path); 
std::istringstream iss("str in gSo met hing");

std::istream A(iss.rdbuf());   // shares the same buffer device with iss

std::string str;

//////////////
while(A >> str) std::cout << str << " | "; //read everything from stream (~> iss)
std::cout << std::endl;

A = std::move(file);
while(A >> str) std::cout << str << " | "; //read from file, using same stream (~> file)