Reputation: 137
I am trying to work with ifstream
and istringstream
using only on variable. I know that both of them are children of istream
. So, I am trying to make only one variable of type istream
and the intialize depending on some input.
The real problem is that I asked the user to input file path or content of file. Then, I will read it line by line. I tried to do like this.
istream * stream;
if(isFile){
ifstream a("fileOrContent");
stream = &a;
} else {
istringstream a("fileOrContent");
stream = &a;
}
getline(stream,line)
// do something with line
I also tried this
ifstream stream;
if(isFile){
ifstream stream("fileOrContent");
} else {
istringstream stream("fileOrContent");
}
getline(stream,line)
// do something with line
Currently, I using two full copies of my code for each one. Any suggestions of how I might do it?
Thank you
Upvotes: 1
Views: 381
Reputation: 10162
What you are trying to do is something like this:
istream * stream;
if(isFile){
stream = new ifstream("fileOrContent");
} else {
stream = new istringstream("fileOrContent");
}
getline(*stream,line)
That said you should use a smart pointer to hold the istream pointer to avoid memory leaks, as pointed out by @πάντα ῥεῖ.
Upvotes: 4
Reputation: 11963
If you don't want to manage the memory yourself, you can use an unique_ptr
which will automatically free the memory when it goes out of scope:
#include <memory>
std::unique_ptr<std::istream> stream;
if(isFile){
stream = std::unique_ptr<std::istream>(new ifstream("fileOrContent"));
} else {
stream = std::unique_ptr<std::istream>(new istringstream("fileOrContent"));
}
getline(*stream,line)
Upvotes: 1
Reputation: 27528
Put the getline
and the "do something with line" in a function which takes a std::istream &
argument.
Then create either an ifstream
or an istringstream
, and place the function call into the if/else branches.
void DoSomethingWithLine(std::istream &stream)
{
getline(stream,line);
// do something with line
}
if (isFile){
ifstream a("fileOrContent");
DoSomethingWithLine(a);
} else {
istringstream a("fileOrContent");
DoSomethingWithLine(a);
}
It won't get much simpler than this.
Upvotes: 0
Reputation: 476990
How about refactoring your code like this:
void process(std::istream & is)
{
// ....
}
int main()
{
if (isFile)
{
std::ifstream is("foo.txt");
process(is);
}
else
{
std::istringstream is(str);
process(is);
}
}
Upvotes: 5
Reputation: 1090
i just did something similar to this. you are almost there
if(isFile) {
stream = new ifstream("whatever");
} else {
stream = new istringstream("whatever");
}
getline(*stream, line);
make sure to delete it though
Upvotes: 1