Search code examples
c++visual-c++ofstream

Creating an ofstream if needed


I am sorry if this is a completely silly question, but I am having trouble with it nonetheless.

I am trying to pass two std::string fileNames to a function foo as follows:

foo(int SomeValue, std::string fileName1, std::string fileName2)

I then want to check whether they both have a have a fileName longer than "" as follows:

bool hasFile1 = true;
if(fileName1.empty())
{
    hasFile1 = false;
}

My problem has been arising since I want to be able to create an ofstream if hasFile1 == true and the same for hasFile2, both of which should be usable later in the function foo.

I have tried doing things like:

std::ofstream file1;
if(hasFile1)
{
    file1 = new std::ofstream(fileName1);
}

but the problem with this is that file1 is an incomplete type. Another method I tried was

std::ofstream* data;
if(hasFile1)
{
    data = new std::ofstream(fileName1)/std::ofstream(fileName1);
}

and all the various combinations all either give a incomplete type not allowed error or I cannot assign to the pointer.

The main point of the question is how do you allocate an ofstream so that you do not need to maintain 3 blocks of code that have various combinations of which ofstreams are being used?

Any help would be much appreciated!!


Solution

  • The "incomplete type" error will be because you haven't included <fstream> to get the definition of ofstream.

    The first won't work because you're trying to assign a pointer (returned by new) to an object. In most cases, you would assign an object instead; but unfortunately streams aren't assignable, even by moving.

    The second would work (once ofstream has been defined), but is a bad idea since you now have a raw pointer to a dynamically allocated resource. You're quite likely not to delete it correctly, giving memory leaks or other problems.

    This can be mitigated by using a smart pointer rather than a raw pointer; but in the case of ofstream, you can simply leave it closed if you don't have a file to open:

    std::ofstream file1;
    if(hasFile1) {
        file1.open(fileName1);
    }
    

    Also, beware that you're not initialising hasFile1 properly; and that you can't usually compare C-style strings using ==. You want something more like

    bool hasFile1 = (fileName1[0] != '\0');
    

    or, if you change the file name arguments to the more friendly std::string

    bool hasFile1 = !fileName1.empty();