IO in Files – Examples and explanation of fgets, fputs, fprintf, fscanf, fread, fwrite

In the previous tutorial, we saw how a user can store a number of characters in a file using the function fputc() along with some other basic operations on file. Now, If we want to store a complete string at one go what should we do? Or what if we want to write numbers in the file or a combination of numbers and characters? Or write a record in a file using structures? Using fputc() will not be very feasible. So we are now going to see other file library functions that allow us to solve these problems.

String I/O in Files

Using a while loop and the function fputc() to store a string or a character array in a file will make the program more complex and a bit inefficient as well. Therefore, to avoid these we have another function fputs() which directly copies the whole string to the file without the use of any loop.Here is the syntax of the fputs() function:

fputs(string_variable,file_pointer);

where the file pointer points to the file where the string is to be added.

Similarly, when reading a String from a file we can simply use the function fgets() to read it from the file instead of using the while loop to retrieve each character from the file one by one.Here is the syntax of the fgets() function:

fgets(string_name, length of the string, file pointer);

Unlike the fputs() function the fgets() function takes three arguments: the name of the variable that will store the string, the length of the string and the file pointer which points to the file from where we have to read the data.

The Program below copies the string in file Doc1.txt to another file Doc2.txt using the functions fgets() and fputs():

#include <stdio.h>
int main() {
  FILE *fp, *fw; // file pointers for the respective read and write mode.
  char s[30];

  fp = fopen("E://Doc1.txt", "r"); // The file that contains the String
  fw = fopen("E://Doc2.txt",
             "w"); // The file from which the string is being copied

  /*while runs until it gets NULL*/
  while (fgets(s, 30, fp) != NULL) { // reading the string from the file
                                     // Doc1.txt
    fputs(s, fw);                    // copying to the file Doc2.txt
    printf("%s", s);
  }
  fclose(fp);
  fclose(fw);
  return 0;
}

Output:-
Codingeek..!!
Hello people...!!

using fgets and fputs


I/O of Records in Files using Structures

In the previous section, we have been dealing with string data only. What if we have a record which contains string data, number data as well as float data? We have already seen that we can easily handle records using structures. Now, the problem arises as to how we can add the numeric data to the file without worrying about the type conversions? This problem can be easily solved using the function fprintf().

fprintf() is very similar to the function printf() and it allows the user to write any type of data into.the file. The only difference being the file pointer present in the arguments.

Similarly, to read any type of data from the file we can use the function fscanf(). fscanf() is similar to scanf() with the only difference being the file pointer present in the arguments. Here is a program that reads the records from one file Doc1.txt and copies it to another file Doc2.txt:

#include <stdio.h>
#include <stdlib.h>
int main() {
  FILE *fp, *fw;
  /*creating a structure to store the particulars of the students from the file
   * Doc1.txt*/
  struct student {
    char name[20];
    int id;
    float marks;
  };
  struct student s;

  fp = fopen("E://Doc1.txt", "r"); // The file from which data is copied
  fw = fopen("E://Doc2.txt", "w"); // the new file into which the data is copied

  /*copying the student record from Doc1.txt to Doc2.txt. The file runs until
   * end of file is reached*/
  while (fscanf(fp, "%s%d%f", &s.name, &s.id, &s.marks) != EOF) {
    fprintf(fw, "%s %d %f", s.name, s.id, s.marks);
    fprintf(
        fw,
        "\n"); // To add new line after every record that is read from the File
  }
  fclose(fp);
  fclose(fw);
  return 0;
}

The Output is shown in the following figure:

StructureIO


Using fwrite() and fread() to read and write data in files

Now, in case we have a lot of data elements or fields in the structure then writing the data or reading the data using the function fprintf() or fscanf() won’t be efficient. Hence we have another function fwrite() to write the structure data into the file and fread() to read the structure data from the file.

The function fwrite() takes four arguments, i.e.,

  1. The address of the structure,
  2. The size of the structure in bytes,
  3. The number of structure that we want to write to the file at a time and
  4. The file pointer.

The program below takes student details from the user and copies it to the file using the function fwrite().

#include <stdio.h>
#include <stdlib.h>
int main() {
  FILE *fw;
  // adding three records to the file. It can be any desired value or can be
  // dependent on user input. It is hard coded only for the sake of simplicity,
  // in real scenarios these are not hardcoded values.
  int count = 3;

  /*creating a structure to store the particulars of the students from the file
   * Doc1.txt*/
  struct student {
    char name[20];
    int id;
    int age;
    float marks;
  };
  struct student s;

  fw = fopen("E://Doc2.dat", "w"); // the new file into which the data is copied

  while (count != 0) {
    printf("Enter the name,id,age and marks of a student:\n");
    scanf("%s %d %d %f", &s.name, &s.id, &s.age, &s.marks);
    fwrite(&s, sizeof(s), 1,
           fw);    // writes the data stored in the function to the file
    fflush(stdin); // to flush out the data remaining in the buffer
    count--;
  }
  fclose(fw);
  return 0;
}

The function fread() takes the same number of arguments,i.e., the address of the structure, the size of the structure, the number of structures whose data is to be read and the file pointer. The program below reads the data that we entered using the fwrite() function from Doc2.dat and prints it:

#include <stdio.h>
#include <stdlib.h>
int main() {
  FILE *fp;
  /*creating a structure to store the particulars of the students from the file
   * Doc1.txt*/
  struct student {
    char name[20];
    int id;
    int age;
    float marks;
  };
  struct student s;

  fp = fopen("E://Doc2.dat", "rb"); // the new file from which data is read
  if (fp == NULL) {
    printf("Cannot open file");
    exit(1);
  }
  /*reading the data from the file using fread()*/
  while (fread(&s, sizeof(s), 1, fp) == 1) {
    printf("%s %d %d %f ", &s.name, &s.id, &s.age, &s.marks);
    printf("\n");
  }
  fclose(fp);
  return 0;
}


Library function fflush()

In the code, we come across a new function called fflush(stdin). This function flushes out all the data that is present in the buffer to the disk. We use this function because of the ambiguity of the scanf() function which stores the enter or new line data in the buffer only unless the file ends.  stdin stands for standard input device or the keyboard in this context.

Note: Also, we see that the file that we created is not a text file but are actually .dat files. The reason being the fact that the text file would occupy more bytes because the characters in a text file are stored in the form of a string. And if we open this file Doc.dat using notepad we will see unidentified symbols.

 

So that’s all for this tutorial. Hope this helps and you like the tutorial. Do ask for any queries in the comment box and provide your valuable feedback. Do come back for more because learning paves way for a better understanding.

Keep Coding!! Happy Coding!! 🙂

Recommended -

Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x
Index