0% found this document useful (0 votes)
23 views30 pages

Unit V Notes

Uploaded by

Dharshan
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
23 views30 pages

Unit V Notes

Uploaded by

Dharshan
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 30

Unit – V

The Preprocessor and Files


----------------------------------------------------------------------------------------------------------------------------
The C Preprocessor – Macro Substitution: Files – Why Files, Opening and Closing a Data file,
reading and writing a data file, processing a data file, unformatted data file, Errors during file
processing
----------------------------------------------------------------------------------------------------------------------------

Preprocessor:

The C preprocessor is a macro processor that is used automatically by


the C compiler to transform your program before actual compilation. It is
called a macro processor because it allows you to define macros.
The C preprocessor provides following type:

 Inclusion of header files : These are files of declarations that can be


substituted into your program.

 Macro expansion: You can define macros, which are abbreviations for
C code, and then the C preprocessor will replace the macros with their
definitions throughout the program.

 Conditional compilation: Using special preprocessing directives, you

can include or exclude parts of the program according to various

conditions.

Preprocessing directives are lines in your program that start with `#'.

The `#' is followed by an identifier that is the directive name.

For example, `#define' is the directive that defines a macro.

Whitespace is also allowed before and after the `#'.


Sr.No. Directive & Description

1 #define

Substitutes a preprocessor macro.

2 #include

Inserts a particular header from another file.

3 #undef

Undefines a preprocessor macro.

4 #ifdef

Returns true if this macro is defined.

5 #ifndef

Returns true if this macro is not defined.

6 #if

Tests if a compile time condition is true.

7 #else

The alternative for #if.

8 #elif

#else and #if in one statement

9 #endif

Ends preprocessor conditional.


Header Files: (#include)

A header file is a file containing C declarations and macro definitions.


we request the use of a header file in our program with the C
preprocessing directive `#include'.
The header files names end with `.h'.
Both user and system header files are included using the preprocessing
directive `#include'

 System header files declare the interfaces to parts of the operating


system. we include them in our program to supply the definitions
and declarations of predefined code.
 User can create their own header file and add in the program if needed.
There are two ways to add header file in program-

#include <file>: It searches for a file named file in a list of directories


specified by you, then in a standard list of system directories.
#include "file": It searches for a file named file first in the current
directory, then in the same directories used for system header files.

Inclusion of header files:


User can create their own header file. Following program explain how to create

Example: Creating an user header Example: use of an user header file


file File name:
File name: fact.h factprogram.c
#include<stdio.h> #include<stdio.h>
int fact(int n) #include “fact.h”
{ int main()
int i=1,f=1; {
while(i<=n) int i,n=5;
{ i=fact(n);
f=f*i; printf(“factorial is %d\n”,i);
i++; }
} Output: factorial is 120
Return f;}
Macro Substitution in C:

Macro substitution directives in C are a powerful feature of the C preprocessor, a tool that
processes your source code before it is compiled. These directives allow you to define macros,
essentially shortcuts or replacements for code snippets. When the program is compiled, all
instances of the macro are replaced by its defined contents.

What is Macro in C?

A macro in C programming is a fragment of code that has been given a name. Whenever the
name is used, it is replaced by the contents of the macro. Macros are processed by the
preprocessor, a step that takes place before the actual compilation of code.

Defined using #define Directive: Macros are defined using the #define directive. For
example, #define PI 3.14159 defines a macro named PI.
No Storage Allocation: Unlike variables, macros don’t allocate storage space. They are
merely replacements done by the preprocessor.

Macro expansion: (#define)


Sample Macros
Syntax:
#define Template_name value

Note: Template_name replace with its value in program.

Example: #define upper 20

when we add above syntax in the program, wherever upper come it


replace with 20
#Include <stdio.h)
#define upper 20;
Int main()
{
int
i,n=5;
i=upper
+n;
printf(“value of i is %d\n”,i);
}
Output: value of i is 25.
Macros with Arguments:
Here user pass an argument with the macro template .
Syntax:
#define Template_name(Arguments,...) (Expression)
Example:
#include<stdio
.h>
# define rectanglearea(a,b) (a*b)
int main()
{
int a,b,area;
printf(“enter a & b value\n”);
scanf(“%d%d”,&a,&b);
area=rectanglearea(a,b);
printf(“area of rectangle is %d\n”,area);
}

Output:
Enter a & b
value 2 5
area of rectangle is 10
Miscellaneous Directives: (#undef)
the #undef directive tells the preprocessor to remove the definitions for the
specified macro. A macro can be redefined after it has been removed by
the #undef directive.
Syntax:
#undef Template_name(Arguments,...) (Expression)

Example:
# define (a*b) //macro definition
rectanglearea(a,b)
# undef rectanglearea(a,b) (a*b) //macro undefined

# define (a*b) //macro redefined


rectanglearea(a,b)

Example 1: Example 2:
#include<stdio.h> #include<stdio.h>
# define area(a,b) # define area(a,b)
(a*b) (a*b) # undef area(a,b)
# undef area(a,b) (a*b) # define area(a,b)
(a*b) (a*b)
int main() int main()
{ {
int a=2,b=11; int a=2,b=11;
printf("area of rectangle is printf("area of rectangle is
%d", area(a,b)); %d", area(a,b));
return 0; return 0;
} }
Output:
Output: area of rectangle is 22
Error // area is not defined macro
Conditional compilation : (#ifdef, #ifndef, #endif)

Using conditional compilation, if user want, compiler to skip over part


of code by using preprocessing commands #ifdef and #endif

Syntax:
#ifdef
macron
ame
Stateme
nt 1;
Statement 1;
.
.
#endif

Example 1: Example 2:

#include<stdio.h> #include<stdio.h>
# define rectanglearea(a,b) # define rectanglearea(a,b)
(a*b) # define upper 2 (a*b) # define upper 2
int main() int main()
{ {
int a,b,area; int a,b,area;
#ifdef upper #ifdef u
printf("enter a & b value"); printf("enter a & b value");
scanf("%d%d",&a,&b); scanf("%d%d",&a,&b);
area=rectanglearea(a,b); area=rectanglearea(a,b);
printf("area of rectangle is %d",area); printf("area of rectangle is
#endif %d",area);
Printf(“\n end of the program”): #endif
return 0; Printf(“\n end of the program”):
} return 0;
}
Output:
enter a & b value Output:
57 end of the program
area of rectangle is
35 end of the program

If macronme has been #defind, the block of code will be processed as


usual; otherwise not.
 Sometimes we can use #ifndef, instead #ifdef.
 #ifndef works exactly opposite to #ifdef.

Example:

#include<stdio.h>
# define
rectanglearea(a,b) (a*b) #
define upper 2
int main()
{
int a,b,area;
#ifndef upper
printf("enter a & b
value");
scanf("%d%d",&a,&
b);
area=rectanglearea(
a,b);
printf("area of rectangle is %d",area);
#endif
Printf(“\n end of the program”):
ret
urn
0;
}
Output:
end of the program

#if, #else, #elif, #endif Directives:

The #if directive is used to test whether an expression evaluate to a


nonzero value or not. If result is non zero(ie true) the subsequent line
of code execute upto #else, #elif or #endif comes; otherwise they are
skipped.

Example: check number is +ve, -ve or zero.

#include<stdio.h>
int main()
{
int num;
printf("enter number");
scanf("%d",&num);
#if num>0
printf("number is +ve\n");
#elif num<0
printf("number is -ve\n");
#else
printf("number is zero\n");
#endif
return 0;
}
Output:
Enter number
25
Number is +ve

File:

In C programming, file is a place on computer disk where information is


stored permanently. Which represents a sequence of bytes ending with
an end-of- file marker(EOF) .

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 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
3.

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 in plain text, they store it in the binary form (0's
and 1's).

They can hold higher amount of data, are not readable easily and
provides a better security than text files.

File Operations

In C, you can perform four major operations on the file, 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

Declaration for file Pointer:

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
*file_pointer_name;
Example: FILE *fp;

Common File Functions

unction 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

Opening a File or Creating a File:

The fopen() function is used to create a new file or to open an existing


file. this function available in stdio.h file
Syntax:

fp= fopen(“filename”, “mode”);

filename is the name of the file to be opened and mode specifies the
purpose of opening the file. Mode can be of following types,
Example:
fp= fopen(“sample.txt”, “w”);

fp= fopen(“sample.txt”, “r”);

mode description
r opens a text file in reading mode

w opens or create a text file in writing mode.

a opens a text file in append mode

r+ opens a text file in both reading and writing mode

w+ opens a text file in both reading and writing mode

a+ opens a text file in both reading and writing mode

rb opens a binary file in reading mode

wb opens or create a binary file in writing mode

ab opens a binary file in append mode

rb+ opens a binary file in both reading and writing mode

wb+ opens a binary file in both reading and writing mode

ab+ opens a binary file in both reading and writing mode

If fopen( ) cannot open "test.dat " it will a return a NULL pointer which
should always be tested for as follows.
Example:
FILE *fp ;
if ( ( fp = fopen( "test.dat", "r" ) ) == NULL )
{
puts( "Cannot open
file") ; exit( 1) ;
}
This will cause the program to be exited immediately if the file cannot
be opened.

Closing a File:

The file (both text and binary) should be closed after


reading/writing. Closing a file is performed using library function
fclose().
Syntax:

fclose(file_pointer_name);
Example:
fclose(fp); //fp is the file pointer associated with 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.
Writing to a text file:

Example 1: Write to a text file using fprintf()

#include<stdio.h>
Int main()

Int num;

FILE *fptr;

fptr = fopen("program.txt","w");

if(fptr == NULL)

printf("Error!");

exit(1);

printf("Enter num: ");

scanf("%d",&num);

fprintf(fptr,"%d",num);

fclose(fptr);

return 0;

This program takes a number from user and stores in the file program.txt.

Reading from a text file

Example 2: Read from a text file using fscanf()


This program reads the integer present in the program.txt file and
prints it onto the screen.

If you succesfully created the file from Example 1, running this


program will get you the integer you entered.
Note: Other functions like fgetchar(), fgetc(),fputc(),fgets(),fputs() etc.
can be used in 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 function fwrite().

The functions takes four arguments: Address of data to be written in


disk, Size of data to be written in disk, number of such type of data and
pointer to the file where you want to write.

fwrite(address_data,size_data,numbers_data,pointer_to_file);

Example 3: Writing to a binary file using fwrite()


#include <stdio.h>

struct threeNum
{
int n1, n2, n3;
};

int main()
{
int n;
struct threeNum num;
FILE *fptr;

if ((fptr = fopen("program.bin","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 = 5n
num.n3 = 5n + 1;
fwrite(&num, sizeof(struct threeNum), 1, fptr);
}
fclose(fptr);
return 0;
}

In this program, you create a new file program.bin 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 fwrite() function as above.

fread(address_data,size_data,numbers_data,pointer_to_file);

Example 4: Reading from a binary file using fread()


#include <stdio.h>
struct threeNum
{
int n1, n2, n3;
};

int main()
{
int n;
struct threeNum num;
FILE *fptr;

if ((fptr = fopen("C:\\program.bin","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 program.bin 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.

Reading & Writing Characters:


Once a file pointer has been linked to a file we can write
characters to it using the fputc() function.
fputc( ch, fp ) ;
If successful the function returns the character written otherwise
EOF. Characters may be read from a file using the fgetc() standard
library function.
ch = fgetc( fp ) ;
When EOF is reached in the file fgetc( ) returns the EOF character
which informs us to stop reading as there is nothing more left in the file.

Example :- Program to copy a file byte by byte

#include
<stdio.h> void
main()
{
FILE *fin, *fout ;
char dest[30], source[30], ch ;

puts( "Enter source file


name" ); gets( source );
puts( "Enter destination file
name" ); gets( dest ) ;

if ( ( fin = fopen( source, "rb" )


) == NULL )
{
puts( "Cannot open input
file ") ; puts( source ) ;
exit( 1 ) ;
}
// open as binary as we don’t know what is in file

if ( ( fout = fopen( dest, "wb" ) == NULL ) )


{
puts( "Cannot open output file ")
; puts( dest ) ;
exit( 1 ) ;
}

while ( ( ch = fgetc( fin ) ) !=


EOF ) fputc( ch , fout ) ;

fclose(
fin ) ;
fclose(
fout ) ;
}

Note : When any stream I/O function such as fgetc() is called the current
position of the file pointer is automatically moved on by the appropriate
amount, 1 character/ byte in the case of fgetc() ;

Appending Data t o Existing File

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.
In general, to append is to join or add on to the end of something. For example,
an appendix is a section appended (added to the end) of a document. In computer
programming, append is the name of a procedure for concatenating (linked)
lists or arrays in some high- level programming languages.
Void main()
{
FILE *pFile; FILE
*pFile2; char
buffer[256];

pFile=fopen("myfile.txt", "r");
pFile2=fopen("myfile2.txt",
"a"); if(pFile==NULL) {
perror("Error opening file.");
}
else {
while(fgets(buffer, sizeof(buffer),
pFile)) { fprintf(pFile2, "%s", buffer);
}
fclose(pFile);
fclose(pFile2);
}

Unformatted Data File

Unformatted data file refers to a category of file operations that reads or writes data as a
stream of bytes without regard to any format. Unformatted I/O in C is carried out with the aid
of functions like fread() and fwrite(). Without formatting, these operations are used to read and
write data directly to and from files.
Syntax:
Syntax for using the fwrite() function to print unformatted data:
fwrite(data, size, count, file pointer);
Here, count is the number of elements to be written, size is the size of each element to be
written, and the file pointer is a pointer to the file where the data will be written.
Syntax for using the fread() method with unformatted input:
fread(data, size, count, file pointer);
In this syntax, a pointer to the buffer where the data will be read, the size of each element to
be read, the number of elements to be read, and a pointer to the file from which the data will
be read.
Example
Let's examine an illustration of unformatted I/O in C:
#include <stdio.h>
int main() {
char data[100];
FILE *fp;

fp = fopen("file.txt", "w+");

fputs("This is an example of unformatted output.", fp);


fseek(fp, 0, SEEK_SET);

fread(data, sizeof (
char), 100, fp);

printf("%s\n", data);
fclose(fp);

return 0;
}
Output:
This is an example of unformatted output

Difference between Formatted and Unformatted files

In C, there are a few distinctions between formatted and unformatted I/O. Some of these
variations include:
1. Unformatted file reads and writes data as a stream of bytes without any format,

whereas formatted file enables you to read and write data in a predefined format.

2. Flexibility: Formatted offers greater options for output formatting and data

representation, whereas unformatted offers less flexibility and is better suited to reading

and writing binary data.

3. Usability: Formatted is more user-friendly for straightforward input and output activities,

whereas unformatted necessitates more code and is better suited for intricate input and

output procedures.

4. Efficiency: Because unformatted doesn't require any formatting or data type

conversion, it is more efficient than formatted .

Error Handling in C

C language does not provide any direct support for error handling. However a few methods and
variables defined in error.h header file can be used to point out error using the return statement
in a function. In C language, a function returns -1 or NULL value in case of any error and a
global variable errno is set with the error code. So the return value can be used to check error
while programming.

What is errno?

Whenever a function call is made in C language, a variable named errno is associated with it.
It is a global variable, which can be used to identify which type of error was encountered while
function execution, based on its value. Below we have the list of Error numbers and what does
they mean.
errno value Error
1 Operation not permitted
2 No such file or directory
3 No such process
4 Interrupted system call
5 I/O error
6 No such device or address
7 Argument list too long
8 Exec format error
9 Bad file number
10 No child processes
11 Try again
12 Out of memory
13 Permission denied

C language uses the following functions to represent error messages associated with errno:
 perror(): returns the string passed to it along with the textual represention of the current
errno value.
 strerror() is defined in string.h library. This method returns a pointer to the string
representation of the current errno value.

#include <stdio.h>
#include <errno.h>
#include <string.h>

int main ()
{
FILE *fp;
/*
If a file, which does not exists, is opened,
we will get an error
*/
fp = fopen("IWillReturnError.txt", "r");
printf("Value of errno: %d\n ", errno);
printf("The error message is : %s\n", strerror(errno));
perror("Message from perror");

return 0;
}

Output

Value of errno: 2
The error message is: No such file or directory
Message from perror: No such file or directory

Other ways of Error Handling


We can also use Exit Status constants in the exit() function to inform the calling function
about the error. The two constant values available for use
are EXIT_SUCCESS and EXIT_FAILURE. These are nothing but macros
defined stdlib.h header file.

#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
extern int errno;

void main()
{
char *ptr = malloc( 1000000000UL); //requesting to allocate 1gb memory space
if (ptr == NULL) //if memory not available, it will return null
{
puts("malloc failed");
puts(strerror(errno));
exit(EXIT_FAILURE); //exit status failure
}
else
{
free( ptr);
exit(EXIT_SUCCESS); //exit status Success
}
}

Here exit function is used to indicate exit status. Its always a good practice to exit a program
with a exit status. EXIT_SUCCESS and EXIT_FAILURE are two macro used to show exit
status. In case of program coming out after a successful operation EXIT_SUCCESS is used
to show successful exit. It is defined as 0. EXIT_Failure is used in case of any failure in the
program. It is defined as -1.

Sample Programs

Writing Data into a file


#include <stdio.h>

int main()
{
FILE *fp;
char writestr[100];
// Read string to write
printf("Enter the string to write :");
gets(writestr);

// Open file in write mode


fp = fopen("program.txt","w+");

// If file opened successfully, then write the string to file


if ( fp )
{
fputs(writestr,fp);
}
else
{
printf("Failed to open the file\n");
}
//Close the file
fclose(fp);
return(0);
}

Reading Data from File

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// Driver code
int main()
{
FILE* ptr;
char ch;

// Opening file in reading mode


ptr = fopen("program.txt", "r");

if (NULL == ptr) {
printf("file can't be opened \n");
}

printf("content of this file are \n");

// Printing what is written in file


// character by character using loop.
do {
ch = fgetc(ptr);
printf("%c", ch);

// Checking if character is not EOF.


// If it is EOF stop reading.
} while (ch != EOF);

// Closing the file


fclose(ptr);
return 0;
}

Reading data from Random Access File

#include<stdio.h>

int main()
{
FILE *fp;
char ch;
fp = fopen("program.txt","r");
if(!fp)
{
printf("Error: File cannot be opened\n");
return 0;
}
//Move forward 6 bytes, thus we won't be seeing the first 6 bytes if we print till the end.
fseek(fp, 6, 0);

while(fread(&ch,sizeof(ch),1,fp)==1)
{
//Here, we traverse the entire file and print its contents until we reach its end.
printf("%c",ch);
}

fclose(fp);
return 0;
}

You might also like