Question

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!!

Was it helpful?

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();

OTHER TIPS

As you pass the strings as pointer, you try to compare them with another pointer (the literal "") which will never be true (unless, of course, you pass the string literal "" and the compiler only keeps one copy of that specific string literal so the pointer to that literal is shared).

Either use std::string for strings, or if you want old C-style string pointer use std::strlen to check for empty strings.

The comparison of a const char* in if(fileName1 == "") might not do what you expect. It compares two const char* pointers, not their values. Use strlen() (check for zero) or strcmp() to compare C strings.

And did you include fstream ?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top