C FILE I/O: Using File Storage

File Input/Output in C Programming Language

c file ioFiles are essential elements in computer storage which contain user data or represent a user document. Files are of image, text, audio, video or other binary data. In this blog post we are going to see how you can read from the disk, write to a disk, using the C FILE I/O interface. Compared to modern programming languages like Python, or Java, FILE I/O in C is still primitive. This blog post walks you  through two examples of FILE I/O in C language – a part of a beginners lessons in C.

File I/O Operations

If you a beginning C user, you may benefit from using the C compiler in small steps. In Windows you can use the Mingw GNU tool chain, Borland C/C++ compilers or Microsoft Visual Studio, or the shell in Linux. Start by typing in the shell,

$ gcc --version

and you should see the following output, then you are ready to dive into C development.

File API in C

To include the file input-output operations in your program you can add the header file definition,

#include <stdio.h>

where the FILE struct exists and the functions,

  1. fopen – open a file, return FILE* struct pointer
  2. fclose – close a file given the FILE* struct pointer of fopen
  3. fprintf – print to file
  4. fscanf – read from file
  5. ftell – show location in file stream
  6. fseek – goto beginning to file stream or end

 

For more details read the manual page on Linux for assert function.

		$ man fopen 

should bring up a page like,

FOPEN(3)                                   Linux Programmer's Manual                                   FOPEN(3)

NAME
       fopen, fdopen, freopen - stream open functions

SYNOPSIS

       #include <stdio.h>

       FILE *fopen(const char *path, const char *mode);
       void fclose(FILE* );

Related functions : Stream Access

You can also move within the file-stream by using the functions, fseek, ftell, and rewind all defined in the same header file. For details pull up the following manual page by typing, $ man fseek

FSEEK(3)                                   Linux Programmer's Manual                                   FSEEK(3)


NAME

       fgetpos, fseek, fsetpos, ftell, rewind - reposition a stream


SYNOPSIS

       #include <stdio.h>

       int fseek(FILE *stream, long offset, int whence);
       long ftell(FILE *stream);
       void rewind(FILE *stream);

Examples – Reading From a File

In this example we read the file on UNIX called ‘/etc/passwd’ which is a historical artifact, listing number of users and their encrypted passwords, and group IDs. Once we open the file with the read attribute, “r”, we extract the contents into a character buffer, called ‘line_data’ variable. We also do some processing to extract the user name – content from start of line upto the ‘:’ character, and print it to console. We keep count of number of users as well.

Putting all this together we see, the listing ‘file_read.c’

#include <stdio.h> 
#include <assert.h> 

/* extract username from the line of  /etc/passwd  */
int main() { 

    const char* fname = "/etc/passwd";
    FILE* fp = fopen(fname,"r");
    assert( fp != NULL );

    char line_data[512] = {0,}, *ptr=NULL;
    int line_no = 0;

    while(! feof( fp ) ) {
        fgets( line_data, 512, fp ); 
        /* remove parts of line after ':' */
        ptr = line_data;

        while(  *ptr !=':' ) {
            ptr++;
        }

        *ptr = '';
        /* output username */
        printf("%d) %s \n",line_no,line_data);
        line_no++;
    }

    printf("Total # users = %d\n",line_no);
    fclose(fp);
    return 0; 
} 

Running the Program

You can download C package for your platform from the source website, C.org, and run the tests and programs as, $gcc file_read.c -o file_read && ./file_read, is the command to interpret the code and then run the program

0) root 

1) daemon 

2) bin 


... <snip>

39) guest-r7Ir02 

40) guest-r7Ir02 

Total # users = 41

Examples – Writing To a File

Using the fprintf() API, is identical to printf() API in C, but taking a extra first argument as FILE pointer can be used to write data to disk. You also need to open a file with the write attribute, “w”. In this example we will name the file “data.txt”. Putting all this together we see, the program, ‘file_write.c’

#include <stdio.h> 
#include <assert.h> 

/* extract username from the line of  /etc/passwd  */

int main() { 
    const char* fname = "/etc/passwd";
    FILE* fp = fopen(fname,"r");
    assert( fp != NULL );
    char line_data[512] = {0,}, *ptr=NULL;
    int line_no = 0;
    FILE *fw = fopen("data.txt","w");


    while(! feof( fp ) ) {
        fgets( line_data, 512, fp ); 
        /* remove parts of line after ':' */
        ptr = line_data;

        while(  *ptr !=':' ) {
            ptr++;
        }
        *ptr = '';

        /* output username */
        fprintf(fw,"%d) %s \n",line_no,line_data);
        printf("%d) %s \n",line_no,line_data);

        line_no++;
    }

    printf("Total # users = %d\n",line_no);
    fprintf(fw,"Total # users = %d\n",line_no);
    fclose(fw);
    fclose(fp);
    return 0; 

}

And when you compile and run the program, like in the previous section, you will get a new file on the disk called “data.txt”. Open and read it in your favorite editor. What do you see?

Summary

Software developers use file as secondary storage for persistent data storage. When program is closed typically all the contents in the RAM will be lost. Typically storing user preferences to disk is a requirement, or intermediate results of a long computation, as well as reading them back into memory when your application is running again from unexpected termination or reloading. You can learn more about databases for computation and storage. Secondary storage applications include database backups, and application features.