views:

352

answers:

4

Hi, I have a program which writes its output using ofstream. Everything works perfectly fine on Windows when compiled with Visual Studio, but it only writes empty file on Linux when compiled with GCC.

ofstream out(path_out_cstr, ofstream::out);
if(out.bad()){
 cout << "Could not write the file" << flush;
}
else{
 cout << "writing";

 out << "Content" << endl;

 if(out.fail()) cout << "writing failed";

 out.flush();
 out.close(); 
}

The directory which is being writen into has 0777 privileges.

The weird thing is: nothing is written, but no error is reported.

The gcc --version is: (Gentoo 4.3.4 p1.0, pie-10.1.5) 4.3.4

I'm aware the code SHOULD work, so I'm more like looking for suggestions, what could be wrong, than for direct code-fix.

EDIT: fwrite seems to fail in exactly the same fashion (nothing is writte, no error is reported).

EDIT: i'm exectuing both the GCC and the program over SSH on my university directory, if it can have any significance. I have sufficient permisssions to exectute and write files (ls . > out.txt works just fine), it only my program which has trouble.

Thanks for help

A: 

Works for me with g++ 4.4.1

Matthew Flaschen
The gcc --version is:(Gentoo 4.3.4 p1.0, pie-10.1.5) 4.3.4I'm aware the code SHOULD work, so I'm more like looking for suggestions, what could be wrong, than for direct code-fix.
CommanderZ
@commanderz: I doubt it's a code problem. Have you tried to change the output directory?
nico
Yes, I tried varoius directories.
CommanderZ
+5  A: 

Works for me, ubuntu g++-4.1.
Have you tried to execute strace ./test and see if there are write() calls over the file?

Arkaitz Jimenez
Yes, the write calls are there
CommanderZ
the write calls are there? Then there is nothing to do with the code. :S I guess `cat "something" > test_file` works?
Arkaitz Jimenez
Oh, now I see there is "Disk quota exceeded" hidden in the strace output. Thanks for help, I didn't know strace.
CommanderZ
Glad you have solved it... this had me stumped!
Johnsyweb
+1  A: 

If the file is being created, I can see know reason why it would not be written.

Check the value of path_out_cstr. On Unix-like systems, paths are separated with forward slashes '/' rather than the MS-DOS-style backslash'\', which may explain the difference in behaviour between the two operating systems.


Updated

Since we failed to catch the failbit | badbit problem for a time, you may wish to try the exception handling approach... this sample will halt after reporting the first failure...

#include <fstream>
#include <iostream>

int main(int argc, char* argv[])
{
    const char* const path_out = argv[1];

    std::cerr.exceptions(std::cerr.goodbit);

    std::ofstream the_file_stream;
    the_file_stream.exceptions(the_file_stream.badbit | the_file_stream.failbit);

    try
    {
        std::cerr << "Opening [" << path_out << "]" << std::endl;
        the_file_stream.open(path_out);

        std::cerr << "Writing" << std::endl;
        the_file_stream << "Content" << std::endl;

        std::cerr << "Flushing" << std::endl;
        the_file_stream.flush();

        std::cerr << "Closing" << std::endl;
        the_file_stream.close();
    }
    catch (const std::ofstream::failure& e)
    {
        std::cerr << "Failure: " << e.what() << std::endl;
    }

    return 0;
}
Johnsyweb
the path_out_cstr is command line argument to the program, so it is what I type into it. Also, I guess if the path was wrong, the file would not be even created.
CommanderZ
You're right, of course. I've provided some sample code which may help catch similar errors in future.
Johnsyweb
+2  A: 

Most likely solution is that the file is failing to open in the constructor due to a problem in the name or path. If the file can't be opened, the failbit rather than the badbit bit would be set so test for that rather than using bad() :

ofstream out(path_out_cstr, ofstream::out); 
if(out.fail()){ 
    cout << "Could not write the file" << flush; 
...

fail() checks if either failbit or badbit is set whereas bad just checks for badbit. BTW I tried your example and it worked no problem so I deliberately made the path bad - still no problem, but when I changed to fail() it picked up on the bad path.

Robin Welch