user98456
user98456

Reputation: 137

initialize object depending on if statement

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

Answers (5)

Emanuele Paolini
Emanuele Paolini

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

bennofs
bennofs

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

Christian Hackl
Christian Hackl

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

Kerrek SB
Kerrek SB

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

DTSCode
DTSCode

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

Related Questions