7

At the end of a simulation, I want to write some results as an appended row to a data file. The code I am using is the following, where you can assume that outFile was correctly allocated as an std::ofstream, that output_file is a std::string containing a valid path to a file that does not yet exist, and that the variables printed out to the file are just int types that get values during the simulation.

outFile.open(output_file.c_str(), std::ios::out | std::ios::app );
outFile << num_nodes << ", " << tot_s << ", " << tot_c << ", " << tot_d << std::endl;
outFile.close();

I've checked whether it correctly opens the file with the ofstream::is_open() function and it returns false. However, I can't figure out why. I've tried it with many different file names and directory paths, all of which I have checked and they are valid (no typos, etc.)

The file being written is just into a folder on the desktop where I create files all the time, so I don't see how it could be a permissions issue. If it was a permissions issue, how can I check that?

Otherwise, what else can be preventing it from writing to the file?

Added:

Following up on the comments, after adding a call to perror(), it is displaying the "No such file or directory" error. The file path in question is:

/home/ely/Desktop/Evolutionary_Dynamics/GamesOnCycle/data/test.data

I want this file to be created, and all the directories in that path exist, it's all spelled correctly, etc., and there are no weird permission issues with the GamesOnCycle folder or its data subfolder. Note that it is a linux system (Ubuntu 11.04) so the forward slashes are correct for the file path, unless I'm missing something that C++ has to have w.r.t. file paths.

ely
  • 74,674
  • 34
  • 147
  • 228
  • 2
    although perror() is c style you can still use it after ofstream.open to get the error message. – keety Apr 04 '12 at 20:59
  • 1
    Are you sure the paths use double backslashes? – chris Apr 04 '12 at 21:00
  • It's on a linux system, so the paths all have forward slashes. It correctly prints out the file name when it is read in from user input, so it's got the right path in the `std::string` at least. – ely Apr 04 '12 at 21:03
  • 3
    Have you made sure it's consistent by outputting `output_file.c_str()` around the time of opening? It's possible that there was an unanticipated change. – chris Apr 04 '12 at 21:05
  • 1
    Do all directories in the path exist? I am unsure if `ofstream` would create directories if any did not exist. – hmjd Apr 04 '12 at 21:08
  • It might be worth trying it without a path, and just using the current directory to see if that works first. It would help narrow down the problem. – chris Apr 04 '12 at 21:11
  • 1
    @hmjd, I just tried it. It doesn't create new directories. You may have pinpointed the issue there. – chris Apr 04 '12 at 21:12
  • 3
    All directories do exist, but @chris was correct in his suggestion. I had inadvertently used the syntax `std::string output_file = ...` at the moment the string gets assigned from user input, but I already declared the variable `std::string output_file` prior to that. Somehow the compiler didn't complain about re-declaring and somehow this led to an empty file name. – ely Apr 04 '12 at 21:12
  • 1
    @EMS: If the second variable is in a different (including inner) scope, you can have multiple variables with the same name. Many compilers will give a warning though. – Mooing Duck Apr 04 '12 at 21:14
  • @EMS, If it's in a different scope, it automatically uses the innermost scope. To use the global scope, use `::output_file`. Glad to help pinpoint the problem. Debugging output sometimes comes in pretty handy :) – chris Apr 04 '12 at 21:15
  • A testament to why I should have been using the `std::string::assign` method. Now fixed. – ely Apr 04 '12 at 21:15
  • FWIW, this sound like a poster boy for http://SSCCE.ORG/. I suspect that if you had reduced the problem to its smallest representation, you would have never had to ask for help. – Robᵩ Apr 04 '12 at 21:15
  • @Mooing Duck -- Unfortunately that's not the case. Both declarations are at the same scope. Both happen inside `main()` and not inside of anything else. – ely Apr 04 '12 at 21:16
  • @Rob -- I agree, mostly. Sometimes though, you can't see the forest for the trees until you ask and someone points out the obvious. I had done a lot of checking on my own first and at all the places where I issued print statements, it was printing out stuff that confirmed correctness. I had never heard of `perror()` before, though, and that was really what helped illustrate the problem. – ely Apr 04 '12 at 21:19

2 Answers2

8

This could be happening due to several reasons.

1) The file is already open.

2) All the directories in the file path are not created.

3) Lack of file permissions.

For an additional reference, please see When will ofstream::open fail?

Community
  • 1
  • 1
josephthomas
  • 3,256
  • 15
  • 20
4

This may sound bad, but are you on windows or linux? If windows, for your file path, do you have it defined with double "\" in your string, or just one? If just one, you aren't putting the characters in your path that you think you are. To be safe, use the "/" character.

So if you had this:

string pathname = "C:\Users\me\Desktop";

That is NOT a valid path. You are escaping "\U", "\m" and "\D" into your string. You'd need this:

string pathname = "C:\\Users\\me\\Desktop";

or

string pathname = "C:/Users/me/Desktop";

The "/" isn't an escape character.

It's what seems likely to me.

Kevin Anderson
  • 6,850
  • 4
  • 32
  • 54