Download as pdf or txt
Download as pdf or txt
You are on page 1of 17

UNIT – 5: File Management

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.
Files
File is a collection of bytes that is stored on secondary storage devices like Hard disk.
OR
A file represents a sequence of bytes on the disk where a group of related data is stored. File is
created for permanent storage of data. It is a readymade structure.
OR
A file is a place on the disk where a group of related data is stored.

All files related functions are available in stdio.h header file.

Types of Files
When dealing with files, there are two types of files
1. Text files
2. Binary files
1. Text files
Text files are the normal .txt files that you can easily create using Notepad or any simple text editors.
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.
They take minimum effort to maintain, are easily readable, and provide least security and takes
bigger storage space.
2. Binary files
Binary files are mostly the .bin files in your computer.
Instead of storing data as plain text, data are stored in the binary form (0's and 1's).
They can store large amount of data, but not readable easily and provides a better security than
text files.

File Operations
In C, we can perform the following operations on the file, either text or binary:
• Naming a file/Creation of new file
• Opening an existing file
• Reading data from file
• Writing data into file
• Closing a file
Input/Output Operation on files
Function Name Description
fopen() create a new file or open a existing file
fclose() closes a file
getc() reads a character from a file
putc() writes a character to a file
fscanf() reads a set of data from a file
fprintf() writes a set of data to a file
getw() reads a integer from a file
putw() writes a integer to a file
fseek() set the position to desire point
ftell() gives current position in the file
rewind() set the position to the begining point

Steps for processing a file


▪ Declare a file pointer
▪ open a file using fopen() function
▪ Process the file using suitable file I/O functions.
▪ close the file using fclose() function.

Declaration of a file
When working with files, you need to declare a pointer of type file. This declaration is needed
for communication between the file and program.
Syntax
FILE *fp;
The variable fp declares as a pointer to the data type FILE. File is a structure that is defined in
standard I/O library.
Opening a file - for creation and edit
The fopen() function is used to create a new file or to open an existing file.
General Syntax :
fp = fopen("filename","mode")
For Example:
fp = fopen("data","r"); // file named data is opened for reading
fp = fopen("test.txt","w"); // file named test.txt is opened for writing
Closing a File
Closing a file is performed using library function fclose().
fclose(fp); //fp is the file pointer associated with file to be closed.

File Opening Modes


Mode Description
R opens a text file in read mode only

W opens a text file in write mode only

A opens a text file in append mode only

r+ opens a text file in read and write mode

w+ opens a text file in read and write mode

a+ opens a text file in read and write mode

Difference between Append and Write Mode


When the mode is ‘write’, a file with the specified name is created, if the file does not exist. The
contents are deleted, if the file already exists.
When the mode is ‘append’, the file is opened with the current contents safe. A file with the
specified name is created if the file does not exist.

The only difference they have is, when you open a file in the write mode, the file is reset,
resulting in deletion of any data already present in the file. While in append mode this will not
happen. Append mode is used to append or add data to the existing data of file(if any). Hence,
when you open a file in Append (a) mode, the cursor is positioned at the end of the present data
in the file.
Input/Output Operations on Files
The getc() and putc() Functions
The simplest file I/O functions are getc and putc. Assume a file is opened with mode w and the
file pointer fp. Then the statement
putc(c, fp);
writes the character contained in the char variable c to the file associated with FILE pointer fp.
Similarly, getc is used to read a character from a file that has been opened in read mode. For
example the statement
c = getc(fp);
would read a character from the file whose file pointer is fp.
The file pointer moves by one character position for every operation of getc and putc. The getc
will return an end-of-file marker EOF, when end of the file has been reached. Therefore, the
reading should be terminated when EOF is encountered.

Example: Program to read data from the keyboard, write it to a file called “input”, again
read the same data from the “input” file, and display it on the screen.

#include<stdio.h>
int main()
{
FILE *fp;
char ch;
fp = fopen("input", "w");
printf("\nEnter data to store into the file...\n");
while( (ch = getchar()) != EOF) // read data from keyboard
{
putc(ch, fp); // write data into the file
}
fclose(fp);

fp = fopen("input", "r");
printf("\nData read from the file...\n");
while( (ch = getc(fp)) != EOF) // read data from the file
printf("%c",ch); // write data to the screen

// closing the file pointer


fclose(fp);
return 0;
}

OUTPUT
Enter data to store into the file...
This is a program to test the file handling
Features in C ^Z
Data read from the file...
This is a program to test the file handling
Features in C
The getw and putw Functions
These are integer oriented functions. They are similar to the getc and putc functions and are used
to read and write integer values. These functions are useful when we deal with only integer data.
The general format is
putw ( ): putting or writing of an integer value to a file.
putw (integer , fp);
Ex: int x = 5;
putw(x,fp);
getw ( ): getting or reading integer value from a file.
Ex: int x;
x = getw (fp);
Formatted File I/O Functions
Syntax of fprintf is
fprintf (fp, “control string”, list);
Example: fprintf(fp1, “%s %d”, name, age);
Syntax of fscanf is,
fscanf(fp, “control string”, list);
Example: fscanf(fp, “%s %d”, name, &age);
Note:
• fscanf is used to read list of items from a file
• fprintf is used to write a list of items to a file.
• EOF – End of file (when EOF encountered the reading / writing should be terminated)

Example:
#include <stdio.h>
main()
{
FILE *fp;
fp = fopen("file.txt", "w"); //opening file
fprintf(fp, "Hello file by fprintf...\n"); //writing data into file
fclose(fp); //closing file
}
RANDOM ACCESS TO FILES
Random file access means that we can take the file pointer to any part of the file for reading or
writing. In general, with small files, we access the files sequentially. In sequential access, we
access the file record by record or character by character. This approach is appropriate if the file
size is small, but what if the file has tens of thousands of records? In random file access, if a file
has 10,000 records and if you want to go to the 9,999th record, you can directly point the file
pointer to this record using the random file access technique. This can be done using the
following functions in C.
1. fseek()
2. ftell()
3. rewind()
fseek()
The fseek() function is used to move the file pointer to a desired location within the file. It is
used to write data into file at desired location.
syntax:
fseek(file_ptr, offset, position);
file_ptr is a pointer to the file concerned.
offset is a number or variable to type long.
position is an integer number. The position can take one of the following three values:
Value Meaning
0 Beginning of file
1 Current position
2 End of file
The offset specifies the number of positions (bytes) to be moved from the location specified by
position. The offset may be positive, meaning move forwards, or negative, meaning move
backwards.
Eg:
fseek (fp, 0L,0); - go to the beginning of the file. (Similar to rewind).
fseek (fp, 0L,1); - Stay at current position (Rarely used)
fseek (fp, 0L,2); - go to the end of the file, past the last character of the file.
fseek (fp, m,1); - go forward by m bytes.
fseek (fp, -m,2); - go backward by m bytes from the end.
rewind()
This function places the file pointer to the beginning of the file, irrespective of where it is present
right now. It takes file pointer as an argument.
Syntax:
rewind( fp);
ftell()
The ftell() function returns the current file position of the specified stream. We can use ftell()
function to get the total size of a file after moving file pointer at the end of file.
syntax:
n = ftell(fp);
n would give the relative offset(in bytes).

FILE STATUS FUNCTIONS / ERROR HANDLING DURING I/O OPERATIONS


The C language provides the following functions to handle file status queries
1. feof() function to test the end of the file
2. ferror() function to test error
3. clearer() to clear error

1.Test End of File: feof() Function


The feof() function is used to check if the end of the file has been reached. If the file pointer is at
end, the function returns 1. If the end of the file is not reached, it returns value 0.
The syntax is
feof(fp);
Where fp is a file pointer for the currently opened file.
2.Test Error: ferror() Function
The ferror() function is used to test the error status of the file. Errors can be created for many
reasons, ranging from bad media (disk, CD, etc.) to illegal operations such as reading a file in the
write state.
The syntax is
ferrer(fp);
Where fp is a file pointer for the currently opened file.
3.Clear Error: clearerr() Function
When an error occurs, the subsequent calls to the ferror() function returns 1 until the error status
of the file is reset. The clearerr() function is used for this purpose.
The syntax is
clearerr(fp);
Where fp is a file pointer for the currently opened file.

Command line arguments


The main function can be created with two methods: first with no parameters (void) and second
with two parameters. The parameters are argc and argv, where argc is an integer and the argv is a
list of command line arguments.
Main function without arguments:
int main()
Main function with arguments:
int main(int argc, char* argv[])

Command line argument is a parameter supplied to the program when it is invoked. Command
line argument is an important concept in C programming. It is mostly used when you need to
control your program from outside. In C, Command line arguments are passed to
the main() method.

• When the main function of a program contains arguments, then these arguments are
known as Command Line Arguments.
• Command line arguments in C are passed to the main function as argc and argv.
• argc is an argument counter that denotes the number of arguments given, while argv[ ] is
an argument vector that represents a pointer array pointing to each parameter passed to
the main program. If no argument is given, the value of argc will be 1.
• The name of the program is stored in argv[0], the first command-line parameter
in argv[1], and the last argument in argv[n-1].

Syntax:

int main(int argc, char *argv[ ])

Here argc counts the number of arguments on the command line and argv[ ] is a pointer array

which holds pointers of type char which points to the arguments passed to the program.

Example:

C:>COMMAND X_FILE Y_FILE

Here argc is three and argv is an array of three pointers to strings as given below

argv[0] ---->COMMAND

argv[1] ---->X_FILE

argv[2] ---->Y_FILE

Example for Command Line Argument – file name for the below program is command.c

#include <stdio.h>
int main(int argc, char *argv[])
{
int i;
printf("\nProgram name: %5s", argv[0]);
if (argc < 2)
{
printf("\n\nNo argument passed through command line!");
} else
{
printf(“\nNo. of Arguments = %d\n”, argc);
printf("\nArgument supplied: ");
for (i = 1; i < argc; i++)
{
printf("%s\t", argv[i]);
}
}
return 0;
}

Run this program as follows in Windows from command line:

Without Argument: When we run the above code, without passing any argument, let’s see the
output of the execution.

C:>command /* file name is command.c while execution */


Output:
Program name is: C:\turboc3\source\command.exe
No argument passed through the command line!

Pass more than single argument: When we run the program by passing one or more than one
argument, say three arguments. Let’s see the output:

C:>command one two three /* arguments to main program are “one, two, three” */
Output:
Program name is: C:\turboc3\source\command.exe
No. of Arguments = 4
Argument supplied: one two three

Note: Remember that argv[0] holds the name of the program and argv[1] points to the first
command line argument and argv[n-1] gives the last argument. If no argument is
supplied, argc will be 1.
Dynamic Memory Allocation
The process of allocating memory at runtime is known as dynamic memory allocation. Library
routines known as memory management functions are used for allocating and freeing memory
during execution of a program. These functions are defined in stdlib.h header file.

Dynamic memory allocation in C language is possible by 4 functions of stdlib.h header file.

1. malloc()
2. calloc()
3. realloc()
4. free()

Function Purpose
Allocates the memory of requested size and returns
malloc()
the pointer to the first byte of allocated space.
Allocates space for an array of elements. initializes
calloc() them to zero and then returns a pointer to the
memory.
Modifies the size of previously allocated memory
realloc()
space.
Frees or empties the previously allocated memory
free()
space.

malloc() function is used for allocating block of memory at runtime. This function reserves a
block of memory of the given size and returns a pointer of type void. This means that we can
assign it to any type of pointer using typecasting. If it fails to allocate enough space as specified,
it returns a NULL pointer.

Syntax:

void* malloc(byte-size);

Example:

int *x;

x = (int *)malloc(50 * sizeof(int)); //memory space allocated to variable x

free(x); //releases the memory allocated to variable x

calloc() is another memory allocation function that is used for allocating memory at runtime.
calloc function is normally used for allocating memory to derived data types such as arrays and
structures. If it fails to allocate enough space as specified, it returns a NULL pointer.
Syntax:

void *calloc(number of items, element-size);

Example:

struct employee
{
char *name;
int salary;
};
typedef struct employee emp;

emp *e1;

e1 = (emp*)calloc(30,sizeof(emp));

realloc() changes memory size that is already allocated dynamically to a variable.

Syntax:

void* realloc(pointer, new-size);

Example:

int *x;

x = (int*)malloc(50 * sizeof(int));

x = (int*)realloc(x,100); //allocated a new memory to variable x

Diffrence between malloc() and calloc()

malloc() method calloc() method


It is generally used to allocate a single memory It is generally used to allocate contiguous
block of the given size (in bytes) during the run- (multiple) blocks of memory of given size (in
time of a program. bytes) during the run-time of a program.
It doesn't initialize the allocated memory block It initializes all the allocated memory blocks
and contains some garbage value. with 0 (zero) value.
calloc() takes two arguments i.e. the number of
malloc() takes a single argument i.e. the size of
elements and the size of one element that are to be
memory block that is to be allocated.
allocated.
syntax: (cast-data-type *)calloc(num, size-in-
syntax: (cast-data-type *)malloc(size-in-bytes)
bytes)
Example : Example :
float *ptr = (float *)malloc(sizeof(float)); float *ptr = (float *)calloc(10, sizeof(float));

/* Program to illustrate the allocation of memory dynamically for one-dimwntional array at


execution time.
Program takes an array of arbitrary size as input and finds the Largest element in the array */
#inclide <stdio.h>
#include <stdlib.h>
int main()
{
int *a, n, i, max;
printf(“|nEnter size of !D array : “0);
scanf(“%d”, &n);
a = (int *) malloc (n * sizeof(int)); /* Dynamically allocate memory for array */
if (a == NULL)
{
printf(“\nMemory allocation failed”);
return 1;
}
printf(“\nEnter %d elements of array \n”, n);
for(i=0; i<n; i++)
scanf(“%d”, &a[i]);
max = a[0]
for (i=1; i<n; i++)
{
if (a[i] > max)
max = a[i];
}
printf(“\nLargest element of array = %d\n”, max)
free(a); /* deallocate memory */
return 0;
}

OUTPUT
Enter size of 1D array : 10
Enter 10 elements of array
10 23 4 -10 20 50 9 15 8 3
Largest element of array = 50

Preprocessor Directives
The preprocessor is a program that processes the source code before it passes through the
compiler. It operates under the control of what is known as preprocessor command lines or
directives. Preprocessor directives are placed in the source program before the main program.
Before the source code passes through the compiler, it is examined by the preprocessor for any
preprocessor directives. If, there are any, appropriate actions as per the directives are taken and
then the source program is handed over to the compiler.

The preprocessor offers several features called preprocessor directives. Each of these
preprocessor directives begins with a # symbol.

Following are the preprocessor directives:

Preprocessor Directive Description


Directives
Macro #define Used to define a macro
substitution #undef Used to undefine a macro
directives
File inclusion #include Inserts a particular header from another file
Directives
#ifdef Returns true if this macro is defined
#ifndef Returns true if this macro is not defined
Conditional #if Tests if a compile time condition is true
Directives #else The alternative for #if
#elif #else an #if in one statement
#endif Ends preprocessor conditional
#error Prints error message on stderr
Miscellaneous
#pragma Issues special commands to the compiler, using a
Directives
standardized method

The preprocessor directives are divided into 3 categories


1. Macro Substitution Directives
2. File Inclusion Directives
3. Compiler Control Directives

1. Macro Substitution Directives


Macro Substitution is a process where an identifier in a program is replaced by a
predefined string composed of one or more tokens.
It has the following form:
#define identifier string

The definition should start with the keyword #define starting from the first column and should
follow by identifier and a string composed of one or more tokens, with at least one blank space
between them. The token may be any text and identifier must be a valid C name. The pre-
processor replaces every occurrence of the identifier in the source code by token.
There are different forms of macro substitution. The most common form is:
1) Simple macro substitution.
2) Argument macro substitution.
Simple macro substitution
Simple string replacement is commonly used to define constants.
Example:
#define PI 3.1415926
#define SIZE 10
#define COUNT 100

It is convention to write all macros in capitals to identify them as symbolic constants. A


definition such as
#define M 5
will replace all occurrences of M with 5, starting from the line of definition to the end of the
program.

Example Program:

#include<stdio.h>
#define TEN 10
void main ()
{
int a=10;
if (a == TEN)
{
print (“The value of a is 10”);
}
}

Output:
The value of a is 10

Argument macro substitution


The pre-processor permits us to define more complex and more useful form of replacements it
takes thefollowing form
#define identifier(f1,f2,f3....fn)string
Notice that there is no space between the macro identifier and the left parentheses. The identifier
f1, f2,….,fn are the formal macro arguments that are analogous to the formal arguments in a
function call.
Example:
#define SQUARE(x) (x)*(x)
If the following statement appears later in the program
area = SQUARE(side);
Then the preprocessor would expand this statement to:
area = (size) * (size);

Example Program:
#include<stdio.h>
#include<conio.h>
#define SQUARE(x) (x)*(x)
int main()
{
int area;
clrscr();
area = SQUARE(10);
printf (“%d”, area);
return 0;
}

Output:
100

Undefining a Macro
If you have created a macro definition, you can use #undef to remove it. #undef directive causes
a defined name to become undefined. This means the pre-processor will no longer make
anymore text substitutions associated withthat word.
A defined macro can be undefined using following the statement:
#undef identifier
Example
#undef PI
#undef SIZE

2. File Inclusion Directives


File inclusion directive causes one file to be included in another. An external file containing
functions or macro definitions can be include as a part of a program so that we need not write
those functions or macro definitions. This is achieved by the preprocessordirective
#include “filename”
Or
#include <filename>
Where filename is the name of the file containing the required definitions or functions. At this
point, the preprocessor inserts the entire contents of the filename into the source code of the
program. When the filename is included within the double quotation marks, the search for the
file is made first in the current directory and then in the standard directories. Otherwise the file is
searched only in the standard directories.
Also it is a general standard that header files are include in angle bracket while user defined files
are include in double quotes.
#include <stdio.h>
and
#include ”myfile.c”

Example program:

#include <stdio.h> /*include a standard header file.*/


#include “myfile.c” /* Include user defined file.*/
int main ()
{
printf(“Notice the use of #Include pre-processor”);
return 0;
}

3. Compiler Control Directives


Following are the compiler control directives:

Directive Purpose
#ifdef Test for a macro definition
#endif Specifies the end of #if
#ifndef Tests whether a macro is not defined
#if Test a compile-time condition
#else Specifies alternative when #if fails

#ifndef
The #ifndef preprocessor directive checks if macro is not defined by #define. If yes, it executes
the code otherwise #else code is executed, if present.
Syntax:
#ifndef MACRO
//code
#endif

Syntax with #else:


#ifndef MACRO
//successful code
#else
//else code
#endif

Let's see a simple example to use #ifndef preprocessor directive.


#include <stdio.h>
#include <conio.h>
#define INPUT
void main()
{
int a=0;
#ifndef INPUT
a=2;
#else
printf("Enter a:");
scanf("%d", &a);
#endif
printf("Value of a: %d\n", a);
getch();
}

Output:
Enter a: 5
Value of a: 5
In this example the INPUT macro is defined, hence, the else code is executed. Asking for input
value for variable ‘a’ and prints its value.

You might also like