In order to work with a disk file, a pointer to a file I/O structure must be initialized. The structure definition, _IO_FILE, can be found in libio.h in the include directory, /usr/include on Linux, but you do not need to know the information that is stored in the structure -- you do not manipulate this structure directly. Rather, you pass arguments to the system function fopen() to indicate how the file will be dealt with. Numerous functions are available for reading from and writing to the file. When you are done with a file, you use the system function fclose() to terminate access.
Sample code is also provided.
To open a file, you must have a pointer variable to the _IO_FILE structure declared in your program. This example uses fpin, an abbreviation for File Pointer for INput.
FILE *fpin;
FILE is defined in stdio.h (which includes libio.h) using the following typedef:
typedef struct _IO_FILE FILE;
This usage of FILE makes program code more portable, because the structure can be defined differently for different operating systems. As a companion to this, making things truly portable, the programmer uses the system I/O functions whose prototypes are specified in stdio.h.
Opening a file is handled using the system function fopen(), which takes two arguments: the filename (including the full path) and the read/write permissions. The following fragment attempts to open for reading a file whose name is stored in the string variable inputfile.
if( (fpin = fopen(inputfile, "r")) == NULL)
{
/* error-handling code */
printf("Problem opening file %s.\n", inputfile);
/* more instructions may be added */
}
The "r" is one of the file-access modes provided in the accompanying table.
Good Programming Practice: Use a string variable to store the path and name of the file, instead of hard-coding the name of the file into the fopen() call. This makes it easier to change the program later to allow the user to specify a file of his choice.
| Normal Access | |
|---|---|
| r | Open existing file for "r"eading |
| w | Open file for "w"riting, destroying the contents; create if necessary |
| a | "A"ppend at end of file; create if necessary |
| Update Access (for fixed-length records) | |
| r+ | Open existing file for "r"eading & writing |
| w+ | Open file for reading & "w"riting, destroying the contents; create if necessary |
| a+ | Open file for reading & writing -- all writing is "a"ppended to the end of the file; create if necessary |
The functions used for reading and writing data are different for variable- and fixed-length records. This info has been gleaned from the man pages.
To get information on this topic, use
man fseek
man fread
To be filled in at a later date...
Closing a file is handled using the system function fclose(), which takes a single argument: the pointer to the FILE struct. fclose() returns an int which can be one of two values: zero (0) or EOF. Zero indicates success; EOF means that the file could not be closed for some reason.
if( fclose(fpin) == EOF)
{
/* error-handling code */
printf("Problem closing file %s.\n", inputfile);
/* more instructions may be added */
}
Good Programming Practice: Always close a file as soon as you are done using it, even though the system may do housekeeping when your program exits. This frees up system resources and helps prevent accidental writing to a file.
Good Programming Practice: Always check for failure. A file which is opened for read-only may not pose a problem, but files being written to which cannot close can spell disaster.
The following program demonstrates how to access files for input and output. The purpose of the program is to create a copy of a file. N.B. There is no bulletproofing included.
/* Copy a file */
#include <stdio.h>
void main()
{
int ch; /* input character */
char inputfile[80], outputfile[80];
FILE *fpin, *fpout; /* input & output struct pointers */
/* get the filenames from the user */
printf("What file do you want to copy? ");
scanf("%s", inputfile);
printf("What file name do you want for the copy? ");
scanf("%s", outputfile);
/* open the files */
fpin = fopen(inputfile, "r");
fpout = fopen(outputfile, "w");
/* copy the file char by char */
while( (ch = fgetc(fpin)) != EOF)
{
fputc(ch, fpout);
}
/* close the files */
fclose(fpin);
fclose(fpout);
}