Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to assign istringstream and ifstream to an istream variable?

I want to have a variable of type istream which can hold either the contents of a file or a string. The idea is that if no file was specified, the variable of type istream would be assigned with a string.

std::ifstream file(this->_path)

and

std::istringstream iss(stringSomething);

to

std::istream is

I've tried just assigning them to the istream variable like I would with other objects that inherit from the same base class, but that didn't work.

How to assign istringstream and ifstream to an istream variable?

like image 635
oddRaven Avatar asked Aug 05 '16 21:08

oddRaven


2 Answers

You can't assign to a std::istream but you can bind to a reference like this:

#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';
    }
}
like image 141
Galik Avatar answered Sep 19 '22 17:09

Galik


Base class pointers can point to derived class data. std::istringstream and std::ifstream both derived from std::istream, so we can do:

//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{});

Now you just have to extract the content using

std::string s;
(*stream) >> s;
like image 28
Rakete1111 Avatar answered Sep 19 '22 17:09

Rakete1111