C64. C Modes explained in detail

Which mode string we'll pass to fopen depends not only on what operations we plan to perform on the file later but also on whether the file contains text or binary data. To open a text file, we'd use one of the mode strings in below table.

Open for reading
Open for writing (file need not exist)
Open for appending (file need not exist)
Open for reading and writing, starting at beginning
Open for reading and writing (truncate if tile exists)
Open for reading and writing (append if file exists)

When we use fopen to open a binary file, we'll need to include the letter b in the mode string.
we see that distinguishes between writing data and appending data. When data is written to a file, it normally over­writes what was previously there. When a file is opened for appending, however, data written to the file is added at the end. thus preserving the file's original contents.
By the way, special rules apply when a file is opened for both reading and writ­ing (the mode string contains the + character). We can't switch from reading to writing without first calling a file-positioning function unless the reading operation encountered the end of the file. Also, we can't switch from writing to reading with­out either calling f flush (covered later in this section) or calling a file-positioning function..
" rb "
Open lor reading
Open for writing (file need not exist)
Open for appending (file need not exist)
Open for reading and writing, starting at beginning
Open for reading and writing (truncate if file exists)
"a+b" or " ab+"
Open for reading and writing (append if file exists)

Closing a File
int fclose(FILE *stream);
The f close function allows a program to close a file that it's no longer using. The argument to f close must be a file pointer obtained from a call of fopen or f reopen (discussed later in this section), f close returns zero if the file was closed successfully; otherwise, it returns the error code EOF (a macro defined in ).
To show how fopen and f close are used in practice, here's the outline of a program that opens the file example. dat for reading, checks that it was opened successfully, then closes it before terminating.

#define FILE_NAME "example.dat"
int main(void) {
FILE *fp;
fp = fopen(FILE_NAME, "r");
if (fp == NULL) {
printf("Can't open %s\n", FILE_NAME); exit(EXIT_FAILURE);
fclose(fp); return 0;
Of course. C programmers being the way they are. it's not unusual to see the call of fopen combined with the declaration of fp:
FILE *fp = fopen(FILE_NAME, "r");
or the test against NULL:
if ((fp = fopen(FILE_NAME, "r") ) == NULL) ….
Attaching a File to an Open Stream
FILE *freopen(const char * restrict filename, const char * restrict mode, FILE * restrict stream);
freopen attaches a different file to a stream that's already open. The most com­mon use of f reopen is to associate a file with one of the standard streams (stdin, stdout, or stderr). To cause a program to begin writing to the file foo, for instance, we could use the following call of freopen:
if (freopen("foo", "w", stdout) == NULL) { /* error; foo can't be opened */
After closing any file previously associated with stdout (by command-line redi­rection or a previous call of f reopen), freopen will open foo and associate it with stdout.
freopen's normal return value is its third argument (a file pointer). If it can't open the new file, f reopen returns a null pointer, (f reopen ignores the error if the old file can't be closed.)
C99 adds a new twist. If filename is a null pointer, freopen attempts to change the stream's mode to that specified by the mode parameter. Implementa­tions aren't required to support this feature, however: if they do, they may place restrictions 011 which mode changes are permitted.

Obtaining File Names from the Command Line
When we're writing a program that will need to open a file, one problem soon becomes apparent: how do we supply the file name to the program? Building file names into the program itself doesn't provide much flexibility, and prompting the user to enter file names can be awkward. Often, the best solution is to have the pro­gram obtain file names from the command line. When we execute a program named demo, for example, we might supply it with file names by putting them on the command line:
demo names.dat dates.dat
int main(int argc, char *argv[])
argc is the number of command-line arguments; argv is an array of pointers to the argument strings, argv [0] points to the program name, argv [1] through argv [argc-1] point to the remaining arguments, and argv [argc] is a null pointer. In the example above, argc is 3, argv [0] points to a string containing the program name, argv [1] points to the string "names . dat", and argv [2] points to the string "dates . dat":

Checking Whether a File Can Be Opened
The following program determines if a file exists and can be opened for reading. When the program is run, the user will give it a file name to check:
canopen file
The program will then print either file can be opened or file can11 be opened. If the user enters the wrong number of arguments on the command line, the program will print the message usage : canopen filename to remind the user that canopen requires a single file name.
/* Checks whether a file can be opened for reading */
int main(int argc, char *argv[])
FILE * fp;
if (argc != 2)
printf("usage: canopen filename\n"); exit(EXIT_FAILURE);
if ((fp = fopen(argv[1], "r")) == NULL) {
printf("%scan'tbeopened\n",argv[l]); exit(EXIT_FAILURE);
printf("%s can be opened\n", argv[l]);
return 0;

Note that we can use redirection to discard the output of canopen and simply test the status value it returns.

Temporary Files
FILE *tmpfile(void);
char *tmpnam(char *s) ;
Real-world programs often need to create temporary files files that exist only as long as the program is running. C compilers, for instance, often create temporary files. A compiler might first translate a C program to some intermediate form, which it stores in a file. The compiler would then read the file later as it translates the program to object code. Once the program is completely compiled, there's no need to preserve the file containing the program's intermediate form. provides two functions, tmpf ile and tmpnam, for working with temporary files.
tmpfile creates a temporary file (opened in "wb+" mode) that will exist until it's closed or the program ends. A call of tmpfile returns a file pointer that can be used to access the file later:
FILE *tempptr;
tempptr = tmpfileO; /* creates a temporary file */
If it fails to create a file, tmpfile returns a null pointer.
Although tmpfile is easy to use. it has a couple of drawbacks: (1) we don't know the name of the file that tmpfile creates, and (2) we can't decide later to make the file permanent. If these restrictions turn out to be a problem, the alterna­tive is to create a temporary file using fopen. Of course, we don't want this file to have the same name as a previously existing file, so we need some way to generate new file names; that's where the tmpnam function comes in.

tmpnam generates a name for a temporary file. If its argument is a null pointer, tmpnam stores the file name in a static variable and returns a pointer to it:
char *filename;
filename = tmpnam(NULL); /* creates a temporary file name */
Otherwise, tmpnam copies the file name into a character array provided by the programmer:
char filename[L_tmpnam];
tmpnam(filename);     /* creates a temporary file name */
In the latter case, tmpnam also returns a pointer to the first character of this array. L_tmpnam is a macro in that specifies how long to make a character array that will hold a temporary file name.

No comments: