Question

I have been working on a project for school, and I have run into an issue. I am trying to avoid hard coding everything in my program, and part of my requirement is to use fstream. Here is what is throwing an error. I am using G++ as my compiler.

void order::printToFile(string file)
{
ofstream output;

try
{
    output.open(file, ios::app);
}

catch(...)
{
    cerr << "An error has occurred";
}

output << this->info.orderID << setw(10) << this->info.type << setw(10) << this->info.quantity << setw(10) << this->info.zip << setw(10) << (this->info.shipCost + this->info.wholesale) << setw(10) << this->info.profit << endl << endl;

output.close();

}

It is giving me the following error:

No matching function to call for 'std::basic ofstream<char>::open( std::string&, const openmode&)'

Can someone give me a hand with this, please? Thanks

Was it helpful?

Solution

No matching function to call for 'std::basic ofstream<char>::open( std::string&, const openmode&)'

A "no matching function" error means that the compiler searched for but could not find an overload that matched the arguments provided at the call site. open() prior to C++11 had one overload which took a buffer of type char const*. This has been updated and in addition to the first overload, open() now supports an argument of type std::string const&.

The problem must be then that your compiler is not C++11 aware. Adding -std=c++11 to the command line should fix the problem. On the other hand, if you can't do so, you can always grab a pointer to the buffer using c_str():

output.open(file.c_str(), ios::app);
//              ^^^^^^^^

Another thing you should know is that IOStreams are designed by default to not throw exceptions. Instead, they reflect stream errors in the form of a bitmask type known as the "stream state". It can be accessed by using the boolean operator method streams support.

You can enable exceptions by setting the appropriate bits in the exceptions() mask, but I wouldn't recommend it for such a simple example. Simply checking the stream after opening it should suffice:

if (std::ofstream output(file.c_str(), std::ios_base::app)) {
    output << "...";
}
else {
    std::cerr << "An error has occurred.";
}

And lastly, streams do not need to be manually closed. When the scope in which they are defined end their destructors will be called which frees the file resource automatically. Calling close() is only needed in cases where you wish to see if it will work, or if you no longer need the file and want output flushed immediately.

OTHER TIPS

Maybe your compiler is not C++11. Try changing

output.open(file, ios::app);

to

output.open(file.c_str(), ios::app);

The ofstream constructor that takes an std::string argument was added in C++11. Assuming your compiler supports it, you need to enable C++11 mode (-std=c++11 for gcc and clang). Otherwise, change the function call to:

output.open(file.c_str(), ios::app);

Also, note that if ofstream fails to open a file, it will not result in an exception, unless you explicitly enable exceptions.

output.exceptions(std::ofstream::failbit);
output.open(file.c_str(), ios::app); // will throw exception if open fails

The other option is to open the file, and then check if it succeeded

output.open(file.c_str(), ios::app);
if(!output) {
  // error occurred, handle it
}

This worked for me with g++ version 4.8.2 on Ubuntu 14.04.

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

void printToFile (string fname) {
    ofstream output;

    try {
        // NOTE: passing fname.c_str() not just fname
        output.open (fname.c_str(), ios::app);
    } catch (std::exception e) {
        cout << "err occurred: " << e.what() << endl;
    }

    output << "foo bar baz" << endl;
    output.close ();
}

int main () {
    printToFile ("foo.txt");
    return 0;
}

I believe your problem is that you're attempting to call open with a std::string instead of a char * as the first arg. See the comment in the code above.

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