Saturday, April 26, 2014

fopen() read/write/create/append brokenness

It's amazing how long fopen() has managed to be around while still having confusing behavior.

The big culprit in my mind is the "a+" mode, which really ought to do the thing I want, which is to open the file read/write, creating it if it doesn't exist, and sure, go ahead and put the file pointer at the end, whatever.  But it has a bizarre behavior of always appending, as if it were fseek()ing to the end just before every write.

"w+" mode would still work fine for that purpose, but it insists on wiping out the file right when it's opened.

And even "r+" mode would work fine, except that it won't create the file if it doesn't exist.

So none of the three available read/write modes do what I figure must be the most common thing, which is to open the file read/write, creating it if it doesn't exist, and not wiping out all the contents.

I'm not even mad at the original authors for omitting that case.  I'm just amazed that nobody has added a mode for that, and that many docs don't go out of their way to mention the funky "a+" behavior.

So, here in 2014, we still have to do things like:

FILE *f = fopen("foo", "r+");
if (f == NULL) {
  f = fopen("foo", "w+");
  if (f == NULL) {
    return FAIL;
  }
}

1 comment:

Braden said...

Looks like GNU C's "c+" mode may work, judging by http://man7.org/linux/man-pages/man3/fopen.3.html and http://www.php.net/manual/en/function.fopen.php .