Understanding C File Handling Functions With Examples

faribasiddiq's Avatar author of Understanding C File Handling Functions With Examples
This is an article on Understanding C File Handling Functions With Examples in C.
Data files are very essential part of in computer programming. The data we use while programming using the variables of different data types, are unavailable after the program execution. So,there is no way to retrieve the data if we further need. Here comes the necessity of data files.

FILE Structure



FILE is a structure that is used for data storage. The structure of FILE is:
Code:
typedef struct
{
    int level;
    unsigned flags;
    char fd;
    unsigned char hold;
    int bsize;
    unsigned char_FAR* buffer;
    unsigned char_FAR* curp;
    unsigned istemp;
    short token;
}FILE;
But for using FILE in our program, we need not go through the members of the FILE structure. We can just use FILE pointer to create and use FILE for different operations.

Prototype

FILE* filePointerName;

Example:
Code:
FILE *fp;
FILE *inFile;
FILE *outFIle

fopen()



Prototype

fopen(“fileName”,”mode”);

Example:
Code:
FILE *fp = fopen("test.txt","w");
FILE *inFile = fopen("test.txt","r");

fclose()



Prototype

fclose(filePointer);

Example:
Code:
FILE *fp = fopen("test.txt","w");
fclose(fp);

File Access Mode



While opening a file, we have to specify the mode for opening the file. Here is a list of different modes for opening any file and usage of these mode.

r - Read mode - Read from a specified file which already exists. If the file doesn’t exist or is not found, this operaiton fails.
r+ - Read mode(+ some others) - Read from and write into an existing file. The file must exist before the operation.
w - Write mode - Create new file with specified name. If the file exists, contents of the file is destroyed.
w+ - Write mode(+ some others) - Write into an file. It also permits to read the data.
a - Append mode - It appends content to the specified file. If the file doesn’t exist, it is created first, and then contents are written into it.
a+ - Append mode(+some others) - Open a file for reading and appending.

Example:

Here is an example of opening a file in write mode. First, a file pointer fp is declared. Then fp is used to open a file named “test.txt” in ‘w’ mode, which stands for write mode.If fp is null, it means that file could not be opened due to any error.
Code:
int main()
{
    FILE *fp;
    fp = fopen("test.txt","w");
    if(fp==NULL)
    {
        printf("Error in openinng file");
    }
    else
    printf("File has been created successfully");
}
In file handling, we will use some data types besides the common data types. Here goes some discussion on these data types:

size_t - It represents the size of any object in byte. For example, the sizeof() function returns the size of any object in size_t type which is unsigned integral type.

fpos_t - It is used to specify a position within a file.

In different portions of the program, we may need to get and set the position of file pointer, Generally, any fpos_t object is filled by callingfgetpos() function and the position is read by fsetpos() function.

Now we will understand in brief the major functions needed for file handling in C.

fputs()



fputs is used to write data in file. Prototype of this function is:

int fputs(const char* str, FILE* stream );

Parameters

str: constant character pointer or string that is to be written in the file.
stream: pointer to the file in which the data is to be written.

Return

Type: integer
Value: On success Non negative value and
On failure: End of file(EOF), setting the error indicator

fgets()



fgets is used to read data from file. Prototype of this function is:

char* fgets(char* str,int count,FILE* stream);

Parameters

str: character pointer that will point to the returned data from file.

count: integer that is the maximum count of character to return from the file.If the number is n, then (n-1) character is returned from the file. If the number of characters is less than n-1, then full data from the file will be returned.

stream: pointer to the file from which the data will be fetch.

Return:

Type: character pointer(char*)
Value: On success String which is read
On failure Null pointer, setting the error indicator

Example fputs and fgets

Code:
int main()
{
    FILE* fp;
    char ch[20];

    fp = fopen("testFile.txt","w");
    if(fp == NULL)
        printf("Error in creating file");
    else

    fputs("This is a test file",fp);
    fclose(fp);

    fp = fopen("testFile.txt","r");

    if(fp == NULL)
    {
        printf("Error in opening file");
    }
    else
    {
        fgets(ch,20,fp);
        printf("\n%s",ch);
    }
    getch();
    return 0;
}
In this example, a file is opened in write mode. After successful opening, a string is put in the file using fputs() function. The file is then closed and again opened in read mode. Next using fgets() function, twenty characters are read from starting position of the file and printed it on the console.

fputc()



It is used to write one by one character in file. Function prototype is:

int fputc ( int character, FILE * stream );

Parameters

character: The character to be written in the file.
stream: pointer to the file in which data will be written.

Return

Type: integer
Value: On success Integer value of the character which is written
On Failure EOF is returned, setting the error indicator.

A character is written in the position specified by the file pointer. After the write operation of every character, file pointer increases by one and moves to the next position.

Example

Code:
int main()
{
    FILE * fp;
    int len, count;
    char buffer[20] = "Good morning";
    len = strlen(buffer);
    fp = fopen ("file.txt","w");
    if (fp == NULL) printf ("Error in opening file");
    else {
        for(count = 0; count < len; count++)
            fputc(buffer[count],fp);
        fclose (fp);
    }
   return 0;
}
In this function, a string is defined at the beginning. After opening a file in write mode, if successfully opened, copy the string by one character after another. Here, fputc() is used to write the character in the file.

fgetc()



It is used to read one by one character from file. Function prototype is:

int fgetc ( FILE * stream );

Parameters

stream: Pointer to the file from which data will be read.

Return

Type: integer
Value: On Success integer value of the character which is read
On Failure Null pointer, setting the error indicator

It returns the character which is currently pointed by the FILE pointer.

Example
Code:
int main()
{
    FILE * fp;
    int count = 0;
    char ch;
    fp = fopen ("file.txt","r");
    if (fp == NULL) printf ("Error in opening file");
    else {
        while((ch = fgetc(fp)) != EOF) 
            count++;
        printf("There are %d words in the file",count);     
        fclose (fp);
    }
    return 0;
}
Here, a file is opened in read mode. Then until the end of file, characters are read from the file(with punctuation and space)using fgetc()and count of characters are increased. When it reaches EOF, total number of character is printed on the screen.

fprintf()



fprintf() works like printf(), with some differences. While printf() works for standard ouput, fprintf() is for file writing. The protype is:

int fprintf(FILE * stream, const char* str);

Parameters

stream: pointer to the file in which the data is to be written.
str: character pointer to the data to be wriitten, which can include the format of the data.

Return

Type: integer
Value: On success number of characters which is written
On Failure Negative number.

Example
Code:
int main()
{
    char* book[] = {"Shonchoyita","Shonchita","Oporajito","Bonolota"};
    char* author[] = {"Rabindranath","Nazrul","Bivutibhushan","Jibonanondo"};
    FILE* fp;
    int count;

    fp = fopen("BookList.txt","w");
    if(fp == NULL)
    {
        printf("Error in opening file");
    }

    else
    {
        for(count = 0; count < 4; count++)
        {
            fprintf(fp,"%-10s %-10s\n",book[count],author[count]);
        }
    }
    fclose(fp);
}
In this example, arrays of book and author are defined. A text file named BookList.txt is opened in write mode. Then the data of book and author is written into this file using a file pointer and fprintf() function.

fscanf()



fscanf() works like scanf() function, with some differences. While scanf() works for standard input, fscanf() is for file reading. The prototype is:

int fscanf(FILE * stream, const char* str);

Parameters

stream: pointer to the file from which the data is to be read.
str: character pointer to the data to be read. It is mainly the format of the data.

Return

Type: integer
Value: On success number of arguments which is filled
On failure error indicator is set and EOF is returned.

Example

Now, we will perform the file read operation using fscanf() function from the BookList.txt file we have created previously.
Code:
int main()
{
    FILE* fp;
    char bookName[50],bookAuthor[50];
    fp = fopen("BookList.txt","r");
    if(fp == NULL)
    {
        printf("Error in opening file");
    }
    else
    {
        while(fscanf(fp,"%s %s",bookName,bookAuthor)!= EOF)
        {
            printf("%-10s \t%-10s\n",bookName,bookAuthor);
        }
    }
}
In this example, existing text file BookList.txt is opened in read mode. Then, using the file pointer, the book name and author name is read from the file using fscanf() funciton and pointed by two characters stored in two character array named bookName and bookArray until the end of file is found. After every read operation, the result is shown in the console using printf() function.

fwrite()



It is used for file writing. Prototype is:

size_t fread(const void* ptr,size_t size,size_t count,FILE* stream)

Parameters:

ptr: pointer to the data which will be stored.
size: the size of data elements (in byte) to be written.
count: number of data elements to be written.
stream: the pointer to the file where the data will be written.

Return

Type: size_t
Value: On success number of elements which are successfully written
On failure zero (0) if the size or count is 0. Error indicator is set.

Example
Code:
int main()
{
    struct book
    {
        char title[20];
        char author[20];
    };
    struct book bengaliBook[4] = {
        "Shonchita","Rabindranath",
        "Shonchoyita","Nazrul",
        "Oporajito","Bivutibhushan",
        "Bonolota","Jibonananda"
    };
    FILE* fp;
    int count;

    fp = fopen("BookList.txt","w");
    if(fp == NULL)
    {
        printf("Error in opening file");
    }
    else
    {
        for(count = 0; count < 4; count++)
        {
            fwrite(&bengaliBook[count],sizeof(bengaliBook[count]),1,fp);    
        }    
    }
    fclose(fp);
    return 0;
}
In this example, a book structure with two member-title and author is declared. A structure array bengaliBook is declared and initialized. Then a file named BookList.txt is opened in write mode. Then, the four elements of the structure array is written in the file, each of which(elements) contains a book title and author name.

fread()



It is used to read data from file. Prototype of the function is:

size_t fread (void* ptr,size_t size,size_t count,FILE* stream)

Parameters

ptr: pointer to memory where the read data will be stored.
size: size of data elements (in byte) to be read.
count: number of data elements to be read.
stream: pointer to the file from which the data will be read.

Return

Type: size_t
Value: On success number of elements which are successfully read.
On failure returns zero (0) if the size or count is 0, Error indicator is set.

Example
Code:
int main()
{
    struct book
    {
        char title[20];
        char author[20];
    }banglaBook;
    
    FILE* fp;
    int count;

    fp = fopen("BookList.txt","r");

    if(fp == NULL)
    {
        printf("Error in opening file");
    }
    else
    {
        for(count = 0; count < 4; count++)
        {
            fread(&banglaBook, sizeof(banglaBook),1,fp);
            printf("%-10s %-10s\n",banglaBook.title,banglaBook.author);
        }
    }
    fclose(fp);
    return 0;
}
In this example, the same book structure is used. A structure variable named banglaBook is declared. Then the text file BookList.txt is opened in read mode. We have written four elements of the book structure array named bengalibook in this text file in previous example. Now we will read those information. Using file pointer, every time we read data from the text file. The size of the read data in every iteration of the loop is equal to the size of the book structure variable banglaBook. Then the read data is displayed in the console.

freopen()



It is used to reopen a file. Prototype is:

FILE *freopen(const char *filename, const char *mode, FILE *stream)

Parameters

filename: Name of the file which is to be re opened.
mode: Access mode of the file .
stream: Pointer to a FILE object that identifies the stream to be reopened.

Return

TYPE: File pointer.
Value: On success pointer to the file which is reopened.
On failure NULL pointer.

The third parameter is the file stream associated with the specified file. The file is accessed with the specified access mode and associates with it the file stream. If this stream is already associated with some other file(s), then this function first closes the files, disassociates the stream, opens the specified file and associates it with the stream.

Example

Code:
int main ()
{
    FILE *fp;
    fp = freopen("file.txt", "w", stdout);
    if(fp == NULL)
        printf("Error in reopening file");
    else 
        printf("hi world from console\n");
    fclose(fp);
    return(0);
}
In this example, freopen() associates stdout with file.txt with write access mode. So, anything available on the stdout stream, is written into file.txt. After running the example, we will see that “hi world from console”, which is available in standard output, has been written in file.txt.

fflush()



It is used to flush buffer. Prototype is:

int fflush ( FILE * stream );

Parameters

stream: Pointer to a file that specifies a buffered stream.

Return

Type: integer
Value: 0 On success.
On failure a number indicating the error type

Use case of fflush() is platform dependent. Generally it is used to clear the output buffer before any input operation.

Example
Code:
char buffer[50];
int main() {
    FILE * fp;
    fp = fopen ("file.txt","r+");
    if (fp == NULL) printf ("Error in opening file"); else {
        fputs ("Brazil",fp);
        fflush (fp);
        fgets (buffer,20,fp);
        fclose (fp);
        return 0;
    }
}
In this example, after between fputs() and fgets() operation, fflush() is used to clear the buffer.

feof()



It is used to check whether end of file for a stream is set or not. Prototype of the function is:

int feof ( FILE * stream );

Parameters

stream - Pointer to a file.

Return

Type: integer
Value: Non zero value if EOF is set for the stream Zero Otherwise.

By using file pointer as a parameter of feof(), we can check whether end of file has been reached or not.

Example

Code:
int main () {
    FILE * fp;
    int n = 0;
    fp = fopen ("file.txt","r");
    if (fp==NULL) printf ("Error opening file"); else {
        while (fgetc(fp) != EOF) {
            continue;
        }
        if (feof(fp)) {
            puts ("End of file");
        } else puts ("Something wrong, error of file not found");
        fclose (fp);
    }
    return 0;
}
In this example, we have read the content of the file by each character till the end of file and have checked whether the end of file is found or not.

fseek()



It is used to set file pointer to any position. Prototype is:

int fseek ( FILE * stream, long int offset, int origin );

Parameters

Stream: pointer to a file.
Offset: Number of bytes or characters from the origin.
Origin: The original position is set here. From this position, using the offset, the file pointer is set to a new position. Generally, three positions are used as origin:

SEEK_SET - Beginning of file
SEEK_CUR - Current position of the file pointer
SEEK_END - End of file

Return

Type: Integer
Value: On success Zero (0)
On failure Non-Zero

Example

Code:
int main () {
    FILE * fp;
    fp = fopen ( "file.txt" , "w" );
    if (fp==NULL) 
           printf ("Error in opening file"); else {
        fputs ( "I am supporter of France." , fp );
        fseek ( fp , 18 , SEEK_SET );
        fputs ( "Brazil" , fp );
        fseek( fp , 0 , SEEK_CUR );
        fputs ( " and Portugal" , fp );
        fclose ( fp );
    }
    return 0;
}
Then using SEEK_SET and offset, the word France is replaced by Brazil. Then by using SEEK_CUR, and position is appended with the string.

ftell()



It is used to get current position of the file pointer. The function prototype is:

long int ftell ( FILE * stream );

Parameters

stream: Pointer to a file.

Return

Type: long integer.
Value: On success value of current position or offset bytes
On failure -1. System specific error no is set

Example

Code:
int main () {
    FILE * fp;
    long int len;
    fp = fopen ("file.txt","r");
    if (fp==NULL) 
          printf ("Error in opening file"); else {
        fseek (fp, 0, SEEK_END);
        len=ftell (fp);
        fclose (fp);
        printf ("The file contains %ld characters.\n",len);
    }
    return 0;
}
In this example, file.txt is opened and using fseek(), file pointer is set to the end of the file. Then, ftell() is used to get the current position, i.e. offset from the beginning of the file.

fgetpos()



It is used to get current position of the file stream. Prototype of the function is:

int fgetpos ( FILE * stream, fpos_t * pos );

This function gets the current position of the file pointer and stores it in fpos_t object. Then we can set the file pointer to this position in any time and perform required operation.

Prameters

stream: Pointer to a file stream.
pos: Pointer to an object that stores the position value.

Return

Type: integer
Value: On success zero(0)
On failure system specific error no.

fsetpos()



It is used to set current position of the file pointer. Function prototype:

int fsetpos ( FILE * stream, const fpos_t * pos );

In the fpos_t pointer pos, a position is specified. The file pointer is then set to this position.

Parameters

stream: Pointer to a file.
pos: Pointer to a fpos_t object. The position to which the file pointer is to be set is previously stored here.

Return

Type: integer
Value: On success zero(0).
On failure system specific error no.

Example fgetpos fsetpos
Code:
int main () {
    FILE * fp;
    fpos_t pos;
    fp = fopen ("file.txt","w");
    if (fp==NULL) 
          printf ("Error in opening file"); else {
        fgetpos (fp, &pos);
        fputs ("France is my favourite team",fp);
        fsetpos (fp, &pos);
        fputs ("Brazil",fp);
        fclose (fp);
    }
    return 0;
}
The above example clarifies both fgetpos() and fsetpos() function. After opening file, fgetpos() is used to get the initial position of the file pointed by file pointer fp and store it into fpos_t pointer pos. Then some text is written into the file, so file pointer is now changed. If we want to set the file pointer to the starting of the file, we can use fsetpos() function. This function sets the current position of the file pointer to the position pointed by fpos_t pointer pos, which is now the initial position of the file.

rewind()



It is used to set the file pointer at the beginning of the file. Function prototype:

void rewind ( FILE * stream );

Parameters

stream: Pointer to a file.

In any stage of the program, if we need to go back to the starting point of the file, we can use rewind() and send the file pointer as the parameter.

Example

Code:
int main () {
    int n;
    FILE * fp;
    fp = fopen ("file.txt","w+");
    if (fp==NULL)
        printf ("Error in opening file"); else {
        fputs ("France is my favorite team",fp);
        rewind (fp);
        fputs("Brazil",fp);
        fclose (fp);
    }
    return 0;
}
In the above example, first, some string is written in the file. Then rewind() is used to set the file pointer at the beginning of the file. Then overwrite a word.

perror()



It is used to print error message. Function prototype:

void perror ( const char * str );

Parameters

str: String that contains the custom error message is provided by the developer. It may be null pointer, if no custom message is intended to provide. Conventionally, application name is used as the parameter.

Handling error message?

Whenever an error occurs, an error no is generated (header file – errno.h). This error no is associated with specific error message.

So, whenever we get an error, we can print the error using perror() to see exactly what happened. But remember, the system error message is platform dependent.

If we want to give a custom error message along with the system error message, we have to sent the error message as a parameter to perror() function like- perror(“custom error message.”). The error message will be printed in stderr(standard error output stream).

The format of printed error message is:
Code:
Custom error message: System error message.
If no custom error message is sent, then only the system error message is printed:
System error message.

Whenever there is a possibility of occurring any error, we should use perrror() function.

Example

Code:
int main () {
    FILE * pFile;
    pFile=fopen ("unexist.ent","rb");
    if (pFile==NULL)
        perror ("The following error occurred"); else
        fclose (pFile);
    return 0;
}
Output:
Code:
ERROR: No such file or directory
Example 2: with no parameter in perror().

Code:
int main () {
    FILE * fp;
    fp = fopen ("fileTest.txt","r");
    if (fp==NULL)
        perror (""); else
        fclose (fp);
    return 0;
}
Output:
Code:
No such file or directory

Binary files



We can handle any binary file and perform the above fucntionalities in those files. The main difference between binary file and text file handling is access mode. We have to add a character ‘b’ with each of access mode while working with binary file. For example, ‘rb’ is used for read mode while ‘wb’ is used for write mode for binary file accessing.

From the above discussion, we have learnt some useful lessons for file handling in C. Hopefully it will help us to perform basic file I/O operations.
shabbir like this