quick.gif

space2.gif

space2.gif

space2.gif

space2.gif

space2.gif

space2.gif

space2.gif

   

space.gif

   

space.gif

  ../images/main/bullet_green_ball.gif File I/O Using C

C language provides function to work with files at both at low level and high level. We will be seeing following.

   

space.gif

  • Opening a file
  • Character I/O from files
  • Closing a file
  • stdin,stdout and stderr
  • Line I/O with files
  • Formatted I/O with files
  • Random access using fseek()
   

space.gif

   

space.gif

  ../images/main/bulllet_4dots_orange.gif Opening a file

In order to open a file, use the function fopen(). Use it as:

   

space.gif

fp = fopen(filename, mode);

   

space.gif

where:

  • Filename is a string that holds the name of the file on disk (including a path like /cs/course if necessary).
  • Mode is a string representing how you want to open the file. Most often you'll open a file for reading ("r") or writing ("w").
   

space.gif

Note that fopen() returns a FILE * that can then be used to access the file. When the file cannot be opened (e.g., we don't have permission or it doesn't exist when opening for reading), fopen() will return NULL.

   

space.gif

Here are examples of opening files:

   

space.gif


  1 FILE *ifp, *ofp;
  2 char *mode = "r";
  3 char outputFilename[] = "out.list";
  4 
  5 ifp = fopen("in.list", mode);
  6 
  7 if (ifp == NULL) {
  8   fprintf(stderr, "Can't open input file in.list!\n");
  9   exit(1);
 10 }
 11 
 12 ofp = fopen(outputFilename, "w");
 13 
 14 if (ofp == NULL) {
 15   fprintf(stderr, "Can't open output file %s!\n", outputFilename);
 16   exit(1);
 17 }
You could download file open_file.c here
   

space.gif

Note that the input file that we are opening for reading ("r") must already exist. In contrast, the output file we are opening for writing ("w") does not have to exist. If it doesn't, it will be created. If this output file does already exist, its previous contents will be thrown away (and will be lost).

   

space.gif

Note: There are other modes you can use when opening a file, such as append ("a") to append something to the end of a file without losing its contents...or modes that allow you to both read and write. You can look up these other modes in a good C reference on stdio.h.

   

space.gif

  ../images/main/bulllet_4dots_orange.gif Reading from or writing to a file:

Once a file has been successfully opened, you can read from it using fscanf() or write to it using fprintf(). These functions work just like scanf() and printf(), except they require an extra first parameter, a FILE * for the file to be read/written.

   

space.gif

Note: There are other functions in stdio.h that can be used to read or write files. Look them up in a good C reference.

   

space.gif

Continuing our example from above, suppose the input file consists of lines with a username and an integer test score, e.g.:

   

space.gif

 in.list
 ------
 foo 70
 bar 98
 biz A+
 ...
   

space.gif

and that each username is no more than 8 characters long.

   

space.gif

We might use the files we opened above by copying each username and score from the input file to the output file. In the process, we'll increase each score by 10 points for the output file:

   

space.gif


  1 char username[9];  /* One extra for nul char. */
  2 int score;
  3 
  4 ...
  5 
  6 while (fscanf(ifp, "%s %d", username, &score)  ! = EOF) {
  7   fprintf(ofp, "%s %d\n", username, score+10);
  8 }
  9 
 10 ...
You could download file open_file1.c here
   

space.gif

The function fscanf(), like scanf(), normally returns the number of values it was able to read in. However, when it hits the end of the file, it returns the special value EOF. So, testing the return value against EOF is one way to stop the loop.

   

space.gif

The bad thing about testing against EOF is that if the file is not in the right format (e.g., a letter is found when a number is expected):

   

space.gif

 in.list
 ------
 foo 70
 bar 98
 biz A+
 ...
   

space.gif

then fscanf() will not be able to read that line (since there is no integer to read) and it won't advance to the next line in the file. For this error, fscanf() will not return EOF (it's not at the end of the file)....

   

space.gif

Errors like that will at least mess up how the rest of the file is read. In some cases, they will cause an infinite loop.

   

space.gif

One solution is to test against the number of values we expect to be read by fscanf() each time. Since our format is "%s %d", we expect it to read in 2 values, so our condition could be:

   

space.gif


 1 while (fscanf(ifp, "%s %d", username, &score) == 2) {
 2    ...
You could download file open_file2.c here
   

space.gif

Now, if we get 2 values, the loop continues. If we don't get 2 values, either because we are at the end of the file or some other problem occurred (e.g., it sees a letter when it is trying to read in a number with %d), then the loop will end.

   

space.gif

Another way to test for end of file is with the library function feof(). It just takes a file pointer and returns a true/false value based on whether we are at the end of the file.

   

space.gif

To use it in the above example, you would do:

   

space.gif


 1 while ( ! feof(ifp)) {
 2   if (fscanf(ifp, "%s %d", username, &score)  ! = 2)
 3     break;
 4   fprintf(ofp, "%s %d", username, score+10);
 5 }
You could download file open_file3.c here
   

space.gif

Note that, like testing != EOF, it might cause an infinite loop if the format of the input file was not as expected. However, we can add code to make sure it reads in 2 values (as we've done above).

   

space.gif

Note: When you use fscanf(...) != EOF or feof(...), they will not detect the end of the file until they try to read past it. In other words, they won't report end-of-file on the last valid read, only on the one after it.

   

space.gif

   

space.gif

   

space.gif

   

space.gif

space2.gif

space2.gif

space2.gif

space2.gif

space2.gif

  

Copyright 1998-2014

Deepak Kumar Tala - All rights reserved

Do you have any Comment? mail me at:deepak@asic-world.com