A File Outta Nowhere

I had such a struggle with file I/O when I first learned computer programming. I knew what a file was and how to create it in an application. With computer programming, however, you enter a lower-level realm that requires more knowledge of file access.

The struggle is between sequential and random file access. Before boring into the details, I present the basic file access elements in the C language:

FILE To access a file, you use a file handle, represented by the FILE variable. FILE is typedef’d in the stdio.h header file as a structure pointer. FILE variables are created with the * operator, but afterwards used without that operator. That way programmers who can’t stand pointers can work with file functions and not suffer an aneurism.

fopen() The function to open a file for reading and writing is fopen(). Its arguments are two strings, a filename and an access mode. This function is defined in the stdio.h header file.

fclose() The function to close a file is fclose(). It writes any left over tidbits to the file and ensures that data is safely stored. Its sole argument is the FILE variable returned from a previously successful fopen() function. It too is defined in stdio.h.

Of these three elements, fopen() is the most involved — which is good, because it’s not that complex. Its second argument is a mode string that stipulates how the file is opened:

"a" to open or create a file for appending.
"r" to open a file for reading only.
"w" to open or create a file for writing.

Both "a" and "w" create a file if it doesn’t exist. The "r" option fails if the file doesn’t exist.

Appending a + character to any mode string also opens the file for reading and writing.

Following "w" or "w+" with the x character causes the fopen() function to fail when the named file already exists.

None of these options set how the data is read from the file, sequentially or via random access. So you can put off being flustered by those options until later.

The following code shows a file-opening skeleton. The file is opened for writing, which means it’s created. If the file indicated already exists, it’s overwritten.

#include <stdio.h>

int main()
{
    const char filename[] = "test";
    FILE *f;

    printf("Creating '%s'\n",filename);
    f = fopen(filename,"w");
    if( f == NULL )
    {
        fprintf(stderr,"Unable to create file '%s'\n",filename);
        return(1);
    }
    fclose(f);
    puts("Done");

    return(0);
}

The filename test is established a string constant at Line 5. Line 6 creates the FILE handle (pointer variable) f.

In Line 9, the fopen() function attempts to open the file. Lines 10 through 14 handle any file errors. You must include this type of testing in all your file-handling code. When the file pointer is NULL, the file cannot be opened (for whatever reason) and you should discontinue accessing it.

Line 15 uses the fclose() function to close the file referenced by FILE handle f.

No data is written to the file test. If you check the directory, you see that file test has zero bytes. That’s exactly what the program did: Create a file for writing, not write anything, then close the file.

To alter the code to open a file for reading, change the "w" argument in Line 10 to "r". You can modify the printf() statement at Line 8 and the fprintf() statement as Line 12 to reflect that a file is being read from and opened for reading. As long as the file test exists, it can be opened and closed.

In next week’s Lesson, I cover writing to a file and reading from a file.

Leave a Reply