Use of `ofstream` appears not to create nor write to file - c++

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.

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?

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.

Related

Phantom \.txt file in windows

It seems like it is possible to create a file \.txt in windows that can be read, but I'm not able to access it any other way or see if it exists. This seems to only work for \.txt since I can't create other files with backslashes in it such as a\.txt
string filename = "\\.txt";
// make file
ofstream writer(filename);
writer << "This file exists" << endl;
writer.close();
// read file
ifstream reader(filename);
string line;
getline(reader, line);
cout << line << endl;
reader.close();
When I use ls -lia in bash, this file doesn't show up at all, but the program above reads it fine (I can remove the part that creates the file and run it later so the file does persists), how does this work?
On Windows, ofstream writer("\\.txt") creates a file named .txt in the root of the current drive. It is a perfectly valid file name.
ofstream writer("a\\.txt") tries to create a file named .txt in the a subdirectory of the current directory. The a directory must exist in order for it to succeed. Most likely it does not exist, therefore it fails for you.
To create a directory you can use either the mkdir function (which has compatibility problems with other OSes because Windows is not POSIX compatible), or the CreateDirectory WINAPI function, that is Windows specific. After calling CreateDirectoryA("a"), the "a\\.txt" path should work.

Is it possible to read and write to a header file?

So I'm trying to overwrite a macro I have on a header file but I can't seem to open it by using std::ifstream. Is it even possible to read/write to an existing header file or are there default permissions that don't allow programs to modify header file contents?
std::ifstream versionH;
char temp[100];
versionH.open("..\temp.h");
if (!versionH.is_open()) {
std::cout << "Didn't open" << std::endl;
return 1;
}
while (!versionH.eof()) {
versionH >> temp;
std::cout << temp << std::endl;
}
I would hope that I'd be able to read in the header file and display it's contents but 'versionH.is_open()' is returning false. Is there something I'm missing here?
Is it possible to read and write to a header file?
Headers are files. It is possible to read and write files (assuming the file exists, and the process has sufficient permissions etc.). Therefore we can infer that header files can be read and written to.
Note that modifying a header file that has been used to compile a program has no effect on the compiled program. It can only affect programs compiled using the modified file.
Furthermore, files in the context where the program is compiled are irrelevant to the program. Only the files in the file system where the program is executed can be read.
Is there something I'm missing here?
Probably the file doesn't exist. The filename is most suspicious. Does it really contain a tab character (\t), or did you intend to write a (windows) dir separator? The backslash is the escape character, so in order to write it in a string literal, you must escape it (with another backslash: \\).

What would cause ifstream code to fail on OS X?

I have the following code
string fileName = "assets/maps/main.json";
std::ifstream file(fileName);
std::string temp;
if(!file.good())
{
LOG(logERROR) << "Failed to open map file: " << fileName;
//return;
}
LOG(logDEBUG) << "file Char Count: " << file.gcount();
while(std::getline(file, temp))
{
mapString += temp;
}
file.close();
This code works superbly on Windows 8. When I take this program over to OS X, the file fails to open 100% of the time. Or to be more concise, file.good() never returns true. I intentionally commented out the return there to help debugging for later code.
Anyway, this has driven me insane. I cannot figure out why it's failing on OS X. I've tried different directories, re-created the file on OS X to make sure it wasn't an encoding or line-end issue, nothing at all.
What else can I do to debug, or what might I try as an alternative?
I've also checked the file permissions themselves and they are all fine. I have many other types of files in the same directory structure (images, music, fonts) and they all open fine, it's just this JSON file that fails, and any new derivatives of this file also fail.
When you start a program on Linux or MacOSX, the working directory will be wherever the user is. So, if your game needs to find files, you need to make use of the appropriate preference system. Mac has a concept of a 'bundle' that allows a program to come with data files and use find them, you'll have to learn how to make one. You can look inside all the '.app' directories in your /Applications directories for many examples.

C++ did not open some existing file

I tried to write some code in C++ that traverses all system files. The problem was that there are some files which returns an error (2) which mean no such file found. Although the path had been found, but cannot been opened or get the pointer on that file or folder!
dirp->search_handle = FindFirstFileA (dirp->patt, &dirp->find_data);
if (dirp->search_handle == INVALID_HANDLE_VALUE)
{
cout << "Error(" << errno << ") opening " << dir<<" erroeno:"<<strerror(errno)<< endl<<endl;
}
The problem is not caused by a lack of administrator permissions because I am an admin on my computer. So what might cause this problem?
There are other reasons you could lack permissions
You could be trying to traverse a directory owned by another user on your domain. Being an Administrator doesn't automatically give you access to all files on a machine.
What you're passing could just have a trivial error. For example, you might have passed "C:\temp", without properly escaping your backslash, and instead getting a tab character.
I would provide more information about what specifically you're passing, or perhaps read up on msdn

C++ text file I/O

This is a very simple question but wherever I look I get a different answer (is this because it's changed or will change in c++0x?):
In c++ how do I read two numbers from a text file and output them in another text file?
Additionally, where do I put the input file? Just in the project directory? And do I need to already have the output file? Or will one be created?
You're probably getting different answers because there are many different ways to do this.
Reading and writing two numbers can be pretty simple:
std::ifstream infile("input_file.txt");
std::ofstream outfile("output_file.txt");
int a, b;
infile >> a >> b;
outfile << a << "\t" << b;
You (obviously) need to replace "input_file.txt" with the name of a real text file. You can specify that file with an absolute or relative path, if you want. If you only specify the file name, not a path, that means it'll look for the file in the "current directory" (which may or may not be the same as the directory containing the executable).
When you open a file just for writing as I have above, by default any existing data will be erased, and replaced with what you write. If no file by that name (and again, you can specify the path to the file) exists, a new one will be created. You can also specify append mode, which adds new data to the end of the existing file, or (for an std::fstream) update mode, where you can read existing data and write new data.
If your program is a filter, i.e. it reads stuff from somewhere, and outputs stuff elsewhere, you will benefit of using standard input and standard output instead of named files. It will allow you to easily use the shell redirections to use files, saving your program to handle all the file operations.
#include <iostream>
int main()
{
int a, b;
std::cin >> a >> b;
std::cout << a << " " << b;
}
Then use it from the shell.
> cat my_input_file | my_program > my_output_file
Put in the same folder as the executable. Or you can use a file path to point at it.
It can be created if it does not exist.