Course Content
Programming in C
About Lesson

In certain situations, our program may need to access a file that is not already connected to the program. For example, cat is a Unix command-line utility which concatenates a set of named files onto the standard output.

cat f1.txt f2.txt

displays the contents of f1.txt and f2.txt on the standard output.
Here, we have written our own version of cat:

#include <stdio.h>

void copy(FILE *, FILE *); 

int main(int argc, char *argv[])
{
  FILE *fp;
  int i;
  if (argc == 1)
    copy(stdin, stdout);
  else {
    for (i = 1; i < argc; i++) {
      fp = fopen(argv[i], "r");
      if (fp) {
        copy(fp, stdout);
        fclose(fp);
      } else {
        printf("Can't open file: %s\n", argv[i]);
      }   
    }   
  }
  return 0;
}

/* Copy file pointed by ifp to file pointed by ofp
 */
void copy(FILE *ifp, FILE *ofp)
{
  int c;
  while ((c = getc(ifp)) != EOF)
    putc(c, ofp);
}

In the above code, we use file pointers which point to structures that contain information about files, such as location of a buffer, current character position in the buffer, file mode (whether file is being read or written), occurrences of errors or end of file. We don’t need to know the details and can directly use the structure FILE (included in stdio.h).

FILE *fp;

says that fp is a pointer to a FILE.
Let’s look at the declaration of fopen:

FILE *fopen(char *name, char *mode);

It takes the file name as its first argument and mode, which indicates how we intend to use the file, as its second argument. Both arguments are character strings. Mode can be read(“r”), write(“w”) or append(“a”). In the above code, we open the input file in read mode.
If there is any error (like trying to open a file that doesn’t exist), fopen returns NULL, otherwise it returns the file pointer.
Once the file is open, we could use the file pointer to read or write.

int getc(FILE *fp);
int putc(int c, FILE *fp);

getc returns the next character from the stream referred to by fp; it returns EOF for end of file or error.
putc writes character c to file pointed by fp and returns the written character or EOF in case of error.

We also have functions fscanf and fprintf for formatted input and output. These are identical to scanf and printf functions, except for the first argument, which is a file pointer.

int fscanf(FILE *fp, char *format, ...);
int fprintf(FILE *fp, char *format, ...);

The function

int fclose(FILE *fp);

frees up the file pointer. Since most operating systems have some limit on the number of files that a program may simultaneously open, it’s a good idea to free file pointers that are no longer needed. fclose also flushes the buffer in which putc is collecting output. fclose is called automatically for each open file, when the program terminates normally.

The file pointers stdin and stdout are constants of type FILE *, and refer to the standard input and standard output streams respectively.

Scroll to Top