C communicates with files using a new data type called a "file pointer". This type is defined within the library stdio.h, and written as FILE *. A file pointer called output_file is declared in a statement like
FILE *fp;
Your program must open a file before it can access it. This is done using the "fopen()" function, which returns the required file pointer. If the file cannot be opened for any reason then the value NULL will be returned. You will usually use "fopen" as follows
if ((fp = fopen("name of the file to open", "w")) == NULL)
fprintf(stderr, "Can't open %s\n", "fp");
"r" or "w" or "a" or "r+" or "w+" or "a+". we will discuss these modes in detail in a later section.
Now let us take a simple program that will read a file and count how many characters, spaces, tabs and newlines are present in that file.====================================================================================main()
{
FILE *fp; /* file pointer fp*/
char ch;
int number_of_lines=0, number_of_tabs=0,
number_of_blanks=0, number_of_char=0;
fp=fopen("ex.c", "r");
while(1)
{
ch = fgetc(fp);
if(ch == EOF) break;
number_of_char++;
if(ch == ' ') number_of_blanks++;
if(ch == '\n') number_of_lines++;
if(ch == '\t') number_of_tabs++;
}
fclose(fp);
printf("Number of characters in the file = %d\n", number_of_char);
}
====================================================================================
FILE *fp;
The FILE structure contains information about the file being used, such as its current size, its location in memory and a character pointer which points to the character that is about to get read. Now lets understand the following statements:
FILE *fp;
/* fp is a file pointer which contains address of the structure FILE*/
fp=fopen("ex.c", "r");
fopen() performs 3 tasks:
- It searches on the disk the file to be opened.
- If the file is presents, it loads the file from the disk into memory.
- It sets up a character pointer which points to the first character of the chunk of the memory where the file is loaded.
To read the file contents in the memory, there exists a function called fgetc().
ch = fgetc(fp);
fgetc() reads the character from the current file pointer position, advances the pointer position so that it now points to the next character, and returns the character it read, which we collected in the variable ch. While reading from the file, when fgetc() encounters the special character whose ASCII value is 26, it returns the macro EOF. The EOF macro has been defined in stdio.h.
Closing the file
When we have finished reading from the file, we need to close it. This is done using the function fclose() through the statement,
flose(fp);
File opening modes
Following is a list of all possible modes in which a file can be opened.
"r" - Reading from the file.
"w" - Writing into the file.
"a" - Appending new contents at the end of the file.
"r+" - Reading existing contents, Writing new contents, modifying existing contents.
"w+" - Writing new contents, Reading them back and modifying the existing contents.
"a+" - Reading existing contents, appending the new contents. Can't modify the existing contents.
stdin - Standard input device (Keyboard);
stdout - Standard output device (VDU);
stderr - Standard error device;
stdaux - Standard auxiliary device;
stdprn - Standard printing device;
Thus the statement ch = fgetc(stdin) would read a character from the keyboard rather than from a file.
fputc(ch, stdprn) writes a character read from the file to the printer.
Text mode versus Binary mode
There are 3 main areas where text and binary mode files are different. These are:
- Handling of new lines
- Representation of end of file
- Storage numbers
I am not going into detail about these things.
Record I/O in files
So far we have seen programs which write characters, strings or numbers to a file. If we desire to write a combination of dissimilar data types, what should we do? We all know, use structures. Following program illustrates the use of structures for writing records of employees.
====================================================================================
/*Writing records to a file using structures*/
#include "stdio.h"main()
{
FILE *fp;
char another ='Y';
struct emp
{
int age;
char name[25];
float basic_sal;
} e;
fp = fopen("Employees_details.txt", "w");
if(fp == NULL)
{
printf("Can't open the write file\n");
exit();
}
while(another == 'Y')
{
printf("Enter the name of the employee, age and his bs\n");
scanf("%s%d%f", &e.name , &e.age , &e.basic_sal);
fprintf(fp, "%s %d %f\n", e.name , e.age , e.basic_sal);
printf("Add another record(Y/N)\n");
fflush(stdin);
another = getchar();
}
fclose(fp);
}
====================================================================================
The above program has two disadvantages:
Guess....???
- The numbers would occupy more number of bytes, since the file has been in text mode. This is because when the file is opened in text mode, each number is stored as a character string.
- If the number of fields in the structure increase, writing structures using fprintf(), or reading them using fscanf(), becomes quite clumsy.
====================================================================================
main()
{
FILE *fp;
char another ='Y';
struct emp
{
int age;
char name[ 25];
float basic_sal;
} e;
fp = fopen("Employees_details.txt", "w");
if(fp == NULL)
{
printf("Can't open the write file\n");
exit();
}
while(another == 'Y')
{
printf("Enter the name of the employee, age and his bs\n");
scanf("%s%d%f", &e.name, &e.age, &e.basic_sal);
fwrite(&e, sizeof(e), 1,fp);
printf("Add another record(Y/N)");
fflush(stdin);
another = getchar();
}
fclose(fp);
} // End of main()
====================================================================================
Consider the statement:
fwrite (&e, sizeof (e), 1, fp);
Here, first argument is the address of the structure to be written to the disk. The second argument is the size of the structure in bytes. Instead of counting the bytes ourselves, we let the program do it for us by using the sizeof() operator. The third argument is the number of structures that we want to write at one time. In this case, we want to write only one structure at a time. The last argument is the pointer to the file we want to write to.
Reference
"Let us C" by Yashavant Kanethkar.
2 comments:
From Argentina, thank you very much! Great Post, very well explain!
Thanks Nicolas, Thanks for your great support.
Post a Comment