views:

183

answers:

3

I have a code that looks like this:

int main () {
  fstream file;
  file.open("test.bin", ios::out | ios::binary);
  if(!file.is_open())
  {
      return -1;
  }
  int n = 3;
  file.write(reinterpret_cast<char*>(&n), sizeof(n));
  file.close();
  return 0;
}

when I run it alone, it exits with -1, so obviously it failed to open "test.bin". However, if I save a blank notepad file as "test.bin", and run it, it works fine. What I am wondering is how I can get my C++ program to automatically generate an empty file "test.bin" if a file called "test.bin" does not already exist.

+2  A: 

I'd assume you could probably just do it by opening and closing a file:

if (GetFileAttributes("test.bin") == INVALID_FILE_ATTRIBUTES)
{
    fstream file;
    file.open("test.bin", ios::out);
    file.close();
}
Smashery
Yep, this creates an empty test.bin. +1.
Cannonade
Probably worth noting that GetFileAttributes is Windows specific (which is fine for the OP, but future arrivals might care).
dmckee
Use stat (2) on a POSIX system.
dmckee
Why do you think it's fine for the OP? The tags don't indicate MSVC. Notepad indicates Windows but MSVC isn't the only compiler for that platform nor is Win32 API necessarily available. @Keand64, please retag/indicate if you want Win32 solutions, otherwise we should stick to the standard.
paxdiablo
+1  A: 

One option is to open for read/write and seek to the beginning of the file.

Then, you may read, write, or do whatever you wish.

John Gietzen
ios:app will force *all* writes to the end of the file.
paxdiablo
+1  A: 

Your code snippet is wrong since it's trying to write to a file that you've opened for input. If you want to write to the file, simply use ios::out instead of ios::in.

If you want to open the file for reading but create it if it does not exist, you can use:

file.open("test.bin", ios::in | ios::binary);
if(!file.is_open()) {
    file.open("test.bin", ios::out | ios::binary);
    int n = 3;
    file.write(reinterpret_cast<char*>(&n), sizeof(n));
    file.close();
    file.open("test.bin", ios::in | ios::binary);
    if(!file.is_open()) {
        return -1;
    }
}

This will initialize the file with the integer 3 as the default contents, if it doesn't already exist.

If it does exist, it will leave the contents alone. In either case, you'll have the file open at the first byte.

paxdiablo