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?
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';
}
}
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;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With