File: A file is a container in computer storage devices used for storing data.
Why files are needed?
When a program is terminated, the entire data is lost. Storing in a file will
preserve your data even if the program terminates.
If you have to enter a large number of data, it will take a lot of time to enter
them all. However, if you have a file containing all the data, you can easily
access the contents of the file using a few commands in C.
You can easily move your data from one computer to another without any
changes.
Types of Files: 1. Text files 2. Binary files
Text files: Text files are the normal .txt files. Which can easily create, using
simple text editors such as Notepad. When you open those files, you'll see all
the contents within the file as plain text. You can easily edit or delete the
contents. These files take minimum effort to maintain, are easily readable, and
provide the least security and takes bigger storage space.
Binary files: Binary files are mostly the .bin files in your computer. Instead of
storing data in plain text, they store it in the binary form (0's and 1's). It hold a
higher amount of data, are not readable easily, and provides better security
than text files.
File Operations: In C, you can perform four major operations on files, either
text or binary:
1. Creating a new file
2. Opening an existing file
3. Closing a file
4. Reading from and writing information to a file
Working with files: When working with files, you need to declare a pointer of
type file. This declaration is needed for communication between the file and
the program.
FILE *fptr;
Opening a file for creation and edit: Opening a file is performed using
the fopen() function defined in the stdio.h header file.
The syntax for opening a file in standard I/O is:
ptr = fopen("fileopen","mode");
For example,
fopen("E:\\cprogram\\[Link]","w");
fopen("E:\\cprogram\\[Link]","rb");
Let's suppose the file [Link] doesn't exist in the location E:\
cprogram. The first function creates a new file named [Link] and
opens it for writing as per the mode 'w'.
The writing mode allows you to create and edit (overwrite) the contents of the
file.
Now let's suppose the second binary file [Link] exists in the
location E:\cprogram. The second function opens the existing file for reading
in binary mode 'rb'. The reading mode only allows you to read the file, you
cannot write into the file.
Mode Meaning of Mode During Inexistence of file
If the file does not exist, fopen() returns
r Open for reading. NULL.
Open for reading in binary If the file does not exist, fopen() returns
rb mode. NULL.
If the file exists, its contents are
overwritten.
w Open for writing. If the file does not exist, it will be created.
If the file exists, its contents are
Open for writing in binary overwritten.
wb mode. If the file does not exist, it will be created.
Open for append. Data is
a added to the end of the file. If the file does not exist, it will be created.
Open for append in binary
mode. Data is added to the
ab end of the file. If the file does not exist, it will be created.
Open for both reading and If the file does not exist, fopen() returns
r+ writing. NULL.
Open for both reading and If the file does not exist, fopen() returns
rb+ writing in binary mode. NULL.
If the file exists, its contents are
Open for both reading and overwritten. If the file does not exist, it will
w+ writing. be created.
wb+ Open for both reading and If the file exists, its contents are
writing in binary mode. overwritten. If the file does not exist, it will
Mode Meaning of Mode During Inexistence of file
be created.
Open for both reading and
a+ appending. If the file does not exist, it will be created.
Open for both reading and
ab+ appending in binary mode. If the file does not exist, it will be created.
Closing a File: The file (both text and binary) should be closed after
reading/writing. Closing a file is performed using the fclose() function.
fclose(fptr);
Here, fptr is a file pointer associated with the file to be closed.
Reading and writing to a text file: For reading and writing to a text file, we
use the functions fprintf() and fscanf().
They are just the file versions of printf() and scanf(). The only difference
is that fprint() and fscanf() expects a pointer to the structure FILE.
Example 1: write a C program to “Write to a text file”
#include <stdio.h>
#include <stdlib.h>
int main()
{
int num;
FILE *fptr;
fptr = fopen("C:\\[Link]","w");//write to
file
if(fptr == NULL)
{
printf("Error!");
exit(1);
}
printf("Enter num: ");
scanf("%d",&num);
fprintf(fptr,"%d",num);
fclose(fptr);//closing the file
return 0;
}
This program takes a number from the user and stores in the
file [Link].
After you compile and run this program, you can see a text
file [Link] created in C drive of your computer. When you open the
file, you can see the integer you entered.
Example 2: Write a C program to “Read from a text file”.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int num;
FILE *fptr;
if ((fptr = fopen("C:\\[Link]","r")) ==
NULL){
printf("Error! opening file");
// Program exits if the file pointer returns
NULL.
exit(1);
}
fscanf(fptr,"%d", &num);//reading num from file
printf("Value of n=%d", num);//printing num
fclose(fptr); //closing file
return 0;
}
This program reads the integer present in the [Link] file and prints it
onto the screen.
If you successfully created the file from Example 1, running this program will
get you the integer you entered.
Other functions like fgetchar(), fputc() etc. can be used in a similar way.
Reading and writing to a binary file
Functions fread() and fwrite() are used for reading from and writing to a
file on the disk respectively in case of binary files.
Writing to a binary file: To write into a binary file, you need to use
the fwrite() function. The functions take four arguments:
1. address of data to be written in the disk
2. size of data to be written in the disk
3. number of such type of data
4. pointer to the file where you want to write.
fwrite(addressData, sizeData, numbersData,
pointerToFile);
Example 3: Write to a binary file using fwrite()
#include <stdio.h>
#include <stdlib.h>
struct threeNum
{
int n1, n2, n3;
};
int main()
{
int n;
struct threeNum num;
FILE *fptr;
if ((fptr = fopen("C:\\[Link]","wb")) ==
NULL){
printf("Error! opening file");
// Program exits if the file pointer
returns NULL.
exit(1);
}
for(n = 1; n < 5; ++n)
{
num.n1 = n;
num.n2 = 5*n;
num.n3 = 5*n + 1;
fwrite(&num, sizeof(struct threeNum), 1,
fptr);
}
fclose(fptr);
return 0;
}
In this program, we create a new file [Link] in the C drive. We declare
a structure threeNum with three numbers - n1, n2 and n3, and define it in
the main function as num.
Now, inside the for loop, we store the value into the file using fwrite().
The first parameter takes the address of num and the second parameter takes
the size of the structure threeNum. Since we're only inserting one instance
of num, the third parameter is 1. And, the last parameter *fptr points to the
file we're storing the data. Finally, we close the file.
Reading from a binary file
Function fread() also take 4 arguments similar to the fwrite() function as
above.
fread(addressData, sizeData, numbersData,
pointerToFile);
Example 4: Read from a binary file using fread()
#include <stdio.h>
#include <stdlib.h>
struct threeNum
{
int n1, n2, n3;
};
int main()
{
int n;
struct threeNum num;
FILE *fptr;
if ((fptr = fopen("C:\\[Link]","rb")) ==
NULL){
printf("Error! opening file");
// Program exits if the file pointer
returns NULL.
exit(1);
}
for(n = 1; n < 5; ++n)
{
fread(&num, sizeof(struct threeNum), 1,
fptr);
printf("n1: %d\tn2: %d\tn3: %d", num.n1,
num.n2, num.n3);
}
fclose(fptr);
return 0;
}
In this program, you read the same file [Link] and loop through the
records one by one.
In simple terms, you read one threeNum record of threeNum size from the
file pointed by *fptr into the structure num. You'll get the same records you
inserted in Example 3.
Getting data using fseek()
If you have many records inside a file and need to access a record at a
specific position, you need to loop through all the records before it to get the
record.
This will waste a lot of memory and operation time. An easier way to get to the
required data can be achieved using fseek(). As the name
suggests, fseek() seeks the cursor to the given record in the file.
Syntax of fseek()
fseek(FILE * stream, long int offset, int whence);
The first parameter stream is the pointer to the file. The second parameter is
the position of the record to be found, and the third parameter specifies the
location where the offset starts.
Whence Meaning
SEEK_SE
T Starts the offset from the beginning of the file.
SEEK_EN
D Starts the offset from the end of the file.
Whence Meaning
SEEK_CU Starts the offset from the current location of the cursor in
R the file.
Different whence in fseek()
Example 5: fseek()
#include <stdio.h>
#include <stdlib.h>
struct threeNum
{
int n1, n2, n3;
};
int main()
{
int n;
struct threeNum num;
FILE *fptr;
if ((fptr = fopen("C:\\[Link]","rb")) ==
NULL){
printf("Error! opening file");
// Program exits if the file pointer
returns NULL.
exit(1);
}
// Moves the cursor to the end of the file
fseek(fptr, -sizeof(struct threeNum),
SEEK_END);
for(n = 1; n < 5; ++n)
{
fread(&num, sizeof(struct threeNum), 1,
fptr);
printf("n1: %d\tn2: %d\tn3: %d\n", num.n1,
num.n2, num.n3);
fseek(fptr, -2*sizeof(struct threeNum),
SEEK_CUR);
}
fclose(fptr);
return 0;
}
This program will start reading the records from the file [Link] in the
reverse order (last to first) and prints it.
fgetc(): It is used to obtain input from a file single character at a time. This
function returns the number of characters read by the function. It returns the
character present at position indicated by file pointer. After reading the
character, the file pointer is advanced to next character. If pointer is at end of
file or if an error occurs EOF file is returned by this function.
Syntax: int fgetc(FILE *pointer)
Where pointer: pointer to a FILE object that identifies the stream on which the
operation is to be performed.
fputc() : It is used to write a single character at a time to a given file. It writes
the given character at the position denoted by the file pointer and then
advances the file pointer. This function returns the character that is written in
case of successful write operation else in case of error EOF is returned.
Syntax: int fputc(int char, FILE *pointer)
Where char: character to be written. This is passed as its int promotion.
pointer: pointer to a FILE object that identifies the stream where the character is to
be written.
fscanf(): it is used to read formatted data from the file
Declaration: int fscanf(FILE *fp, const char *format, …)
Example: fscanf (fp, “%d”, &age);
Where, fp is file pointer to the data type “FILE” and Age – Integer variable
fprintf(): it is use to write formatted data into a file.
Declaration: int fprintf(FILE *fp, const char *format, …)
Example: fprintf (fp, “%s %d”, “var1”, var2);
Where, fp is file pointer to the data type “FILE”, var1 – string variable, var2 – Integer
variable
ftell(): it is used to get the current position of the file pointer.
Declaration: long int ftell(FILE *fp);
Example: ftell(fp);
rewind(): it is used to move file pointer position to the beginning of the file.
Declaration: void rewind(FILE *fp)
Example: rewind(fp);
Demonstration of file methods such as fprintf, fscanf, ftell, frewind.
This program reads from the file and write to the file using above methods.
#include <stdio.h>
int main ()
{
char name [20];
int age, length;
FILE *fp;
fp = fopen ("[Link]","w");
fprintf (fp, "%s %d", “MCAregularFirstSem”, 17);
length = ftell(fp); // Cursor position is now at the end of file
/* You can use fseek(fp, 0, SEEK_END); also to move the cursor to the end of
the file */
rewind (fp); // It will move cursor position to the beginning of the file
fscanf (fp, "%d", &age);
fscanf (fp, "%s", name);
fclose (fp);
printf ("Name: %s \n Age: %d \n", name , age);
printf ("Total number of characters in file is %d", length);
return 0;
}
Command line arguments in C/C++: argc and argv:
The most important function of C/C++ is main() function. It is mostly defined with a return type of int and
without parameters :
int main() { /* ... */ }
We can also give command-line arguments in C and C++. Command-line arguments are given after the
name of the program in command-line shell of Operating Systems.
To pass command line arguments, we typically define main() with two arguments : first argument is the
number of command line arguments and second is list of command-line arguments.
int main(int argc, char *argv[]) { /* ... */ }
or
int main(int argc, char **argv) { /* ... */ }
argc (ARGument Count) is int and stores number of command-line arguments passed by the user
including the name of the program. So if we pass a value to a program, value of argc would be 2
(one for argument and one for program name). The value of argc should be non negative.
argv(ARGument Vector) is array of character pointers listing all the arguments. If argc is greater
than zero, the array elements from argv[0] to argv[argc-1] will contain pointers to strings.
Argv[0] is the name of the program , After that till argv[argc-1] every element is command -line
arguments.
For better understanding run this code on your linux machine.
// Name of program [Link]
#include <iostream>
using namespace std;
int main(int argc, char** argv)
{
cout << "You have entered " << argc
<< " arguments:" << "\n";
for (int i = 0; i < argc; ++i)
cout << argv[i] << "\n";
return 0;
}
Input:
$ g++ [Link] -o main
$ ./main geeks for geeks
Output:
You have entered 4 arguments:
./main
geeks
for
geeks
Note : Other platform-dependent formats are also allowed by the C and C++ standards; for example,
Unix (though not POSIX.1) and Microsoft Visual C++ have a third argument giving the program’s
environment, otherwise accessible through getenv in stdlib.h: Refer C program to print environment
variables for details.
Properties of Command Line Arguments:
1. They are passed to main() function.
2. They are parameters/arguments supplied to the program when it is invoked.
3. They are used to control program from outside instead of hard coding those values inside the code.
4. argv[argc] is a NULL pointer.
5. argv[0] holds the name of the program.
6. argv[1] points to the first command line argument and argv[n] points last argument.
Note : You pass all the command line arguments separated by a space, but if argument itself has a
space then you can pass such arguments by putting them inside double quotes “” or single quotes ”.
// C program to illustrate command line arguments
#include<stdio.h>
int main(int argc,char* argv[])
{
int counter;
printf("Program Name Is: %s",argv[0]);
if(argc==1)
printf("\nNo Extra Command Line Argument Passed Other Than
Program Name");
if(argc>=2)
{
printf("\nNumber Of Arguments Passed: %d",argc);
printf("\n----Following Are The Command Line Arguments
Passed----");
for(counter=0;counter<argc;counter++)
printf("\nargv[%d]: %s",counter,argv[counter]);
}
return 0;
}
Output in different scenarios(Linux output):
1. Without argument: When the above code is compiled and executed without passing any
argument, it produces following output.
$ ./[Link]
Program Name Is: ./[Link]
No Extra Command Line Argument Passed Other Than Program Name
2. Three arguments : When the above code is compiled and executed with a three arguments, it
produces the following output.
$ ./[Link] First Second Third
Program Name Is: ./[Link]
Number Of Arguments Passed: 4
----Following Are The Command Line Arguments Passed----
argv[0]: ./[Link]
argv[1]: First
argv[2]: Second
argv[3]: Third
3. Single Argument : When the above code is compiled and executed with a single argument
separated by space but inside double quotes, it produces the following output.
$ ./[Link] "First Second Third"
Program Name Is: ./[Link]
Number Of Arguments Passed: 2
----Following Are The Command Line Arguments Passed----
argv[0]: ./[Link]
argv[1]: First Second Third
4. Single argument in quotes separated by space : When the above code is compiled and
executed with a single argument separated by space but inside single quotes, it produces the
following output.
$ ./[Link] 'First Second Third'
Program Name Is: ./[Link]
Number Of Arguments Passed: 2
----Following Are The Command Line Arguments Passed----
argv[0]: ./[Link]
argv[1]: First Second Third