Thursday, May 15, 2008

union , enum , typedef :

union

The keyword union is useful in defining a new data type like a structure. Its usage is also similar in syntax to a structure. But conceptually union and structures differ in the way they manage memory.In a structure memory is allocated for each member . In Union same memory is shared by all data members

Thus a structure variable requires memory = sum of the memory requirements of all its members

A union variable requires memory = maximum memory requirement of one member

Thus union allows us to interpret the same memory location

in different ways .

union sample

{

int x ;

float y ;

char ch ;

} p ;

Thus here p occupies 4 bytes. Byte 0 is interpreted as char ch . Byte 0 , byte1 together as int x , .All the four bytes together are read as float y . Changing the value of one data member may affect value of all other members.


Program:

union A

{

int x ;

char ch[2] ;

};

void main( )

{

union A var ;

var.x = 260 ;

printf(“%d %d” , var.ch[0] , var.ch[1] );

var.ch[0] += 10 ;

printf(“\nx = 5d” , var.x );

var.ch[1] += 2 ;

printf(“\nx = %d” , var.x);

}

Memory allocated for var => 2 Bytes or 16 bits

var.x = 260 -> 0000 0001 0000 0100

var.ch[0] - > 0000 0100 /* prints 4 */

var.ch[1] - > 0000 0001 /* prints 1 */

var.ch[0] += 10

var.ch[0] - > 0000 1110 /* now 14 */

var.x -> 0000 0001 0000 1110 /* now 270 */

var.ch[1] += 2 ;

var.ch[1] - > 0000 0011 /* 3 */

var.x - > 0000 0011 0000 1110

/* 512 + 256 + 14 = 782 */

Application of unions :-

There is a frequent requirement while interacting with hardware that the same data be interpreted differently

For e.g : Unions are useful in reading and manipulating CPU registers and availing various BIOS services (calling int86( ) function)

CPU registers are 2 bytes in size .We may access the information they store as 2 bytes entirely or as two information of one byte each.

What is an interrupt ?

An interrupt means to stop doing something and instead do something else. Keyboard interrupts are generated by pressing control key , (and or) alt keys , shift key along with some other key. An operating system has a table of interrupt numbers (Interrupt Vector Table IVT) and actions to be taken when the interrupt is encountered.

For e.g

ctrl + C : by pressing ctrl + C (^C) you might stop some

process

PrintScreen : By pressing the PrintScreen key you are generating an interrupt

An interrupt is serviced by the Operating system

You can call various dos interrupt services using int86( ) function (include

Declaration:

int int86(int intno, union REGS *inregs, union REGS *outregs);

inregs holds the values of A , B , C, D registers that are set before the function call

outregs holds the values of A , B , C , D registers after the call

Return Value:

The functions returns the value of AX register after completion of the software interrupt.

Programs: int86( ) function

#include

#include

#include

#define VIDEO 0x10

void movetoxy(int x, int y)

{

union REGS regs;

regs.h.ah = 2; /* set cursor position */

regs.h.dh = y;

regs.h.dl = x;

regs.h.bh = 0; /* video page 0 */

int86(VIDEO, &regs, &regs);

}

­

REGS

REGS (union)

The union REGS is used to pass information to and from these functions . It is defined as follows :-

union REGS {

struct WORDREGS x;

struct BYTEREGS h;

};

BYTEREGS and WORDREGS

Structures for storing byte and word registers

struct BYTEREGS {

unsigned char al, ah, bl, bh;

unsigned char cl, ch, dl, dh;

};

struct WORDREGS {

unsigned int ax, bx, cx, dx;

unsigned int si, di, cflag, flags;

};

Enumerated Data Types :-

The keyword enum helps us to define named integral constants .The advantage :

Improved readability and program documentation.

We use #defines to define constants. Here the datatype is not specific .But with enums the constants are of type int .

Program:

enum status { false , true };

here the constant false is assigned a value 0 and the constant true is assigned a value 1

We may have a code line such as

return true ;

or found = false ;

Program:

enum colors { red , green , blue } ;

Here the constant red has a value 0 , green 1 , blue 2

You might write code like

COLOR background, foreground;

background = blue ;
foreground = red;

Values may be redefined as

enum E1 { c1 = 100 , c2 , c3 };

In this case c1 is assigned a value 100 , c2 = 101 , c3 = 102 and so on .

By default the named constants take incremental values starting with 0 ( 0 , 1 , 2 , 3 .... )
One is free to change these values while defining such as

enum sample { x = 1 , y = 10 , z = 20 } ;
or
enum sample { a , b , c = 10 , d , e , f = 100 , g , h };
here values of a to h are a = 0 , b = 1 , c = 10 , d = 11 , e = 12 , f = 100 , g = 101 , h = 102

The C std library includes lot of enums and one can freely use them in code. IF given a choice between #define and enum in code, one is adviced to use enums liberally instead of #defines as the latter do not pin down the data type while enums are always considered integral constants.

typedef :

The keyword typedef helps to rename datatypes or create datatypes to suit our needs . We can create user defined datatypes based on basic types like int, char, float, double or derived types like struct, union etc. Advantage is ability to call data type by a name that better defines its values and the code is better documented.

For e.g
typedef unsigned int number ;

/* program calls int by another name number */

number age ;
number quantity ;

The advantage is improved readability and program documentation .

typedef int boolean ;

typedef unsigned int WORD ;

You might now declare a variable as

Boolean status ;

WORD x ;

typedef are useful in structures

typedef struct

{

char *title ;

char *author ;

float cost ;

}Book ;

Book is a datatype we have defined .We might declare a variable

Book b1 , b2 ;

Note :

The keyword struct is not used while using data type Book to declare a variable.

Graphics in C

Basic concepts for computer generated Graphics:

A computer draws a picture (graphics) as a combination of dots(pixels) in different colors in different positions . This graphics is displayed on a monitor or sent to a printer .

Concept 1 : Monitor resolution

The monitor may display the output in text mode or graphics mode.

Text Mode :

In text mode (DOS) the monitor displays 80 characters in 25 lines [ 80 X 25 ] .

Graphics Mode :

In graphics mode the monitor resolution is measured in terms of pixels number of dots that can be displayed in each row and column.This resolution is determined by :-

  • The type of display adapter card we are using
  • The Operating System’s monitor display specification that we have set
  • Greater the resolution finer the picture .

Concept 2 :Graphics are mathematical in origin

Graphics are based on some mathematical algorithms (formula or equations or principles). For e.g a circle has an equation and to draw a circle you generate a set of points of points(x , y ) satisfying that equation.

Concept 3 :Graphical Functions in C

C has a number of library functions for managing simple graphical programs . Include header file

You may also write your own functions to create specific graphical objects .The graphics.h header file also includes several constants (enums) that we can use in our programs

Concept 4 : Graphics files like .jpg , .bmp , .gif

When we draw graphics using graphical packages like paintbrush the files get saves in a specific file format like with extensions like .bmp , .jif , .gpg etc. These files store data about the various graphical functions and data structures , data etc into a persistent storage device(hard disk) that helps us to retrieve the picture as and when we want.

Concept 5 : initgraph( ) function in C

A graphics program in C requires to call the initgraph() function that initializes the graphical system by loading a graphics driver from the system .initgraph() also resets all the graphical settings like color , palette , current position … to their defaults . It then resets graphresult to 0.

Declaration:

void far initgraph(int far *graphdriver, int far *graphmode,

char far *pathtodriver);

*graphdriver :- Integer that specifies the graphics driver to

be used.

*graphmode :- Integer that specifies the initial graphics

mode (unless *graphdriver = DETECT).

If *graphdriver = DETECT, initgraph sets *graphmode to the highest resolution available for the detected driver. You can give graphmode a value using a constant of the graphics_modes enumeration type.

pathtodriver : Specifies the directory path where initgraph

looks for graphics drivers (*.BGI) first.

If they're not there, initgraph looks in the current directory. If pathtodriver is null, the driver files must be in the current directory.

This is also the path settextstyle searches for the stroked character font files (*.CHR).

Return Value of initgraph( ) function:

initgraph sets the internal error code On success code is set to to 0 and On error, initgraph sets *graphdriver to -2, -3, -4, or -5, and graphresult returns the same value.

Note :

*graphdriver and *graphmode must be set to valid graphics drivers and graphics mode values or you'll get unpredictable results.

(The exception is graphdriver = DETECT for auto detection.)

After a call to initgraph, *graphdriver is set to the current graphics driver, and *graphmode is set to the current graphics mode.

Program:

#include

#include

#include

#include

int main(void)

{

int gdriver = DETECT, gmode, errorcode;

initgraph(&gdriver, &gmode, "c:\\tc\\bgi");

errorcode = graphresult();

if (errorcode != grOk)

{ _

printf("Graphics error: %s\n", grapherrormsg(errorcode));

printf("Press any key to halt:");

getch();

exit(1);

}

line(0, 0, getmaxx(), getmaxy());

getch();

closegraph();

return 0;

}

Concept 6 : Graphical library functions are available. One can use them to create graphical images.

Some Common functions are:

arc( ) ,bar( ) ,bar3d( ), circle( ) , closegraph ( ) , drawpoly( ) , ellipse ( ) , fillellipse( ), fillpoly ( ), floodfill( ), getbkcolor( ) getcolor( ) , getimage( ) , getmaxx ( ) , getmaxy( ), getpixel , getx( ) , gety ( ) , line( ), lineto ( ) , moveto ( ) , outtext( ) ,

outtextxy( ), pieslice ( ) , putimage( ) , putpixel( ), rectangle( ) , setbkcolor ( ) , setcolor( ) , setfillpattern ( ) , setfillstyle( ) , setlinestyle ( ) , settextjustify( ) , settextstyle( ) , textheight( ) , textwidth( )

bgi.exe is a graphics demo file bundled with Borlands Turboc and one can learn a lot by going through the source code bgi.c

Bitwise Operators

A bit is 0 or 1 . All data in the computer is stored in the binary format as streams of 0 , 1.


Bitwise operators act on each bit of data of the operands. Thus associativity is immaterial in case of bitwise & , | , ^ , ` operators.

Bitwise operators are applicable to only integral operands

Following are bitwise operators:

& Bitwise and

| Bitwise or

~ Bitwise Not or Complment

^ Bitwise XOR (Exclusive or)

>> Right Shift

<< Left Shift

Assignment operators combined with bitwise operators :-

&=

|=

^=

>>=

<<=


Bitwise ‘and’ & Operator : (called anding) is a binary operator that returns 1 if both operands are 1 else returns 0 . Acts on each bit of data .

Program 1 :- Bitwise & operator

void main( )

{

char x = 100 , y = 53 , z ;

clrscr( );

z = x & y ;

printf(“z = %d” , z ); /* prints z = 36 */

}

x è 0110 0100 /* 100 */

y è 0011 0101 /* 53 */

z = x & y è 0010 0100 /* 36 */

Bitwise ‘or’ | Operator : is a binary operator that returns 1 if any one operand is 1 else returns 0 . Acts on each bit of data .

Program 2 :- Bitwise | operator

void main( )

{

char x = 100 , y = 53 , z ;

clrscr( );

z = x | y ;

printf(“z = %d” , z ); /* prints z = 117 */

}

x è 0110 0100 /* 100 */

y è 0011 0101 /* 53 */

z = x | y è 0111 0101 /* 117 */

Bitwise XOR ^ Operator : (mutually excusive or) is a binary operator that returns 1 if any one operand is 1 and one operand is 0 .If both are 1 or both are zero , ^ operator returns 0 . Acts on each bit of data .

Program 3:-

void main()

{

char x = 100 , y = 53 , z ;

clrscr( );

z = x ^ y ;

printf(“z = %d” , z ); /* prints z = 81 */

}

x è 0110 0100 /* 100 */

y è 0011 0101 /* 53 */

z = x ^ y è 0101 0001 /* 81 */

Bitwise Complement or not ~ Operator : is a unary operator that toggles bits if 1 then it becomes 0 and vice versa. Acts on each bit of data .

Program 3:-

void main()

{

char x = 100 , z ;

clrscr( );

z = ~y ;

printf(“z = %d” , z ); /* prints z = */

}

x è 0110 0100 /* 100 */

z = ~x è 1001 1011 /* - 101 */

How is 1001 1011 interpreted ?

Since the left most bit or the most significant bit (msb) is on , the data is negative. We must take a 2’s complement to find the numerical value

Z è 1001 1011

1’s complement è 0110 0100

Add 1 1

2’s Complement è 0110 0101 /* -101 */

Shift Operators :- >> , <<

The bits get shifted to left or right positions

A shift is not a rotation .This means the bits shifted out on the right side will not come and fill up from the left side.

Bit representation of x :

x >> 2

For e.g

If x = 0110 0110 then x << style=""> 1001 1000

If x = 0110 0110 then x << style=""> 0011 0000

If x = 0110 0110 then x >> 2 will give 0010 0110

If x = 0110 0110 then x >> 3 will give 0010 0110

Right Shift of a negative number :-

In case of a negative number , the left most bit is set to 1 . A right shift results in 1’s fill in from the left side to fill up instead of 0’s

If x = 1110 0110 then x >> 2 will give 1111 1001

If x = 1110 0110 then x >> 3 will give 1111 1100

Assignment operators with Bitwise operators :-

&= An expression like x &= y is equivalent to x = x & y

|= An expression like x |= y is equivalent to x = x | y

^= An expression like x ^= y is equivalent to x = x ^ y

>>= An expression like x >>= y is equivalent to x = x >> y

<<= An expression like x <<= y is equivalent to x = x <<>

Application of bitwise operators :-

While software programs are byte oriented, hardwares are bit oriented.As bitwise operators act on each bit of data , One byte of information can be treated as 8 pieces of informations .Each information can be checked and manipulated.



For e.g video memory stores 1 byte for each character attributes .This 1 byte represents 8 bits of information of screen attributes of fore color, back color as shown above.

File Encryption program using bitwise complement ~ operator:

Encryption means changing the contents of a file into an illegible format for protection .Pass the file name to a command called encrypt as a command parameter

For e.g:

C:> encrypt file1

This call changes the contents of file1 into an illegible format.

/*

File encryption

command line encryption

Bitwise complement used for encryption

*/

# include

# include

main(int argc , char *argv[])

{

char ch ;FILE *fp , *ft ;

if(argc != 2)

{

printf("Error in no. of arguments");

printf("\nEncryption Failue");

exit(1);

}

if(!(fp = fopen(argv[1] , "r")) )

{

printf("Error opening file to be encrypted");

printf("\nEncryption Failue");

exit(1);

}

if(!(ft = fopen("temp" , "w")) )

{

printf("Error creating encryption file ");

printf("\nEncryption Failue");

exit(1);

}

while(!feof(fp) )

{

ch = fgetc(fp);

fputc(~ch , ft);

}

remove(argv[1]);

rename("temp" , argv[1]);

printf("\nFile Successfully encrypted");

return 0 ;

}

File Decryption program :

Decryption means restoring the contents of an encrypted file Pass the file name to a command called decrypt as a command parameter

For e.g:

C:> decrypt file1

This call recovers the file encrypted by the above encryption call

/*

File decryption

File name passed as a command line argument

Bitwise complement used for decryption

*/

# include

# include

main(int argc , char *argv[])

{

char ch ;FILE *fp , *ft ;

if(argc != 2)

{

printf("Error in no. of arguments");

printf("\nDecryption Failue");

exit(1);

}

if(!(fp = fopen(argv[1] , "r")) )

{

printf("Error in file Decryption Recovery”);

printf("\nDecryption Failue");

exit(1);

}

if(!(ft = fopen("temp" , "w")) )

{

printf("Error while decrypting ");

printf("\nDecryption Failure");

exit(1);

}

while(!feof(fp) )

{

ch = fgetc(fp);

fputc(~ch , ft);

}

remove(argv[1]);

rename("temp" , argv[1]);

printf("\nFile Successfully decrypted");

return 0 ;

}

Tuesday, May 13, 2008

Command Line Arguments

Command Line Arguments

  • An executable file of C is called as a command
  • We may pass arguments to this command while calling it for execution from the operating system environment Such arguments are known as commandline arguments
  • When a command is executed the function main() is called . The arguments are passed to main( ) function
  • The function main( ) takes two arguments

First argument is an int

Second argument is an array of char pointers

Prototype of main( ) function is :-

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

or

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

int argc : number of arguments passed .This includes the command itself .

char *argv[ ] : Each pointer points to the starting address of each argument . argv[0] holds the address of the command itsef

Note:

All arguments and the command itself are treated as strings These arguments are passed at the operating system level.

Steps are :-

Write the source code (.c file)

Compile and Generate an exe file (.exe file)

Call this exe file at the command prompt by passing appropriate argument values .

For e.g

Write a program that counts down a number passed to it as a command line argument

Source file name : countdn.c

Executable file name countdn.exe

Command countdn

Case 1 : Suppose you run the program as

C:>countdn 5

Your output should be

Counting Down …. 5 4 3 2 1 0 Off !!

Case 2 : Suppose you run the program as

C:>countdn 10

Your output should be

Counting Down …. 10 9 8 7 6 5 4 3 2 1 0 Off !!

Case 3 : Suppose you run the program as

C:>countdn

Your output should be Nothing to Count Down !!

Case 4 : Suppose you run the program as

C:>countdn “asd”

Your output should be

Error : Non Numeric argument passed

Usage : countdn number

Case 5 : Suppose you run the program as

C:>countdn 2 4 5

Your output should be

Error : Invalid number of arguments passed

Usage : countdn number

Step1 :

Type and save the following source code with the name countdn.c

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

{

int j ;

clrscr( );

if ( argc == 1 ) /* case 3 No value passed */

{

printf(“\aNothing to Count Down !!”);

return 1 ;

}

if ( argc > 2 ) /* case 5 More than one value passed

{

printf(“\aError : Invalid number of arguments passed \n Usage : countdn number”);

return 2 ;

}

j = atoi( argv[1] ); /* convert “5” to number 5 */

if( j == 0 ) /* case 4 : A non numeric string was passed */

{

printf(“\a\nError : Non numeric argument passed \n Usage : countdn number”);

return 3 ;

}

printf(“Counting Down…….”);

while(j >= 0 )

{

printf(“%5d” , j);

--j ;

}

printf(“ Off !! “);

return 0 ;

}

Step 2 :

Compile and generate countdn.exe . The command is countdn

Step3 :

Run the command at Command prompt as :

C:> countdn 10

Program 2 :-

Write a program greet that greets the username passed as commandline argument depending on the time of the day

# include

# include

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

{

struct time t;

int j ;

char str[20];

gettime(&t);

if( t.ti_hour <>

strcpy(str , "Good morning" ) ;

else

if( t.ti_hour >= 12 && t.ti_hour <= 16 )

strcpy(str , "Good Afternoon" );

else

if( t.ti_hour > 16 && t.ti_hour <>

strcpy(str , "Good Evening" );

else

strcpy(str , "Good Night");

if(argc == 1 )

{

printf("%s The whole world" , str );

return 1 ;

}

for(j = 1 ; j <>

printf("\n%s %s" , str , argv[j] );

return 0;

}

Monday, May 12, 2008

I/O Redirection:

Normally a C program takes its input from the keyboard (standard input device) and sends its output to the screen or terminal ( standard output device) But in cases where we would like to take input or output from other sources (other than the standard devices) we use what is known as redirection . The redirection operators are ">" for output , "<" for input



/* File name is test1.c */

#include

#include

main( )

{

char ch ;

printf(“\n Enter ^z to terminate input”);

while ( (ch = getchar() ) != EOF)

putchar(ch );

getch();

}

This program takes input from keyboard and prints it on screen . Suppose the exe file generated by this source code is test1.exe then the output of this program can be redirected at the DOS prompt as

C:>test2.exe > trytest2.txt

Here the output of test1.exe instead of being printed on screen is redirected to another file trytest1.txt .

This file can then be read at DOS prompt by the dos command type C:>type trytest2.txt

This will print the contents of the file on screen .

C:>test2.exe > PRN

This command will accept text from the keyboard and redirect the output of test2.exe to the printer .

Suppose we have a file called Sample.txt containing the following text “There is no limit to what can be accomplished if it does not matter matter who gets the credit”

We can take input from this file using redirection at the DOS prompt as

C:>test.exe < text.c

In this case the contents of the file Text.c will be printed on the screen without us doing anything or giving any input from the keyboard.

File I/O

Disk based I/O

File :

A file is data written to a persistent storage device like the hard disk or floppy drive . Normally data in a computer is stored and retrieved from a temporary storage device which is known as memory [ RAM] If we wish to store this data for future reference then we will have to write this data to a permanent (persistent)storage device like the hard disk .

Some fundamental concepts regarding file I/O :-

1. Role of operating system ( O.S ) in File I/O

You might create a file in C , C++ , VB , Word etc… But underlying any of these applications is the O.S. It is the O.S that manages the hardware . It interfaces between the H/W and the application .Tit is the OS that reads , writes data to files .It manages the file system .This means as a C programmer , one must know the OS rules regarding file naming conventions , directory structures etc.

2.Block r/w and byte r/w

Data moves from memory to CPU and I/O devices. Both CPU and memory are fast , electrical devices and bytes of data move to and fro . But the I/O devices like the hard disk , floppy drive are electro mechanical devices . The disk rotates during read writes. It would be very slow if the r/w are byte by byte. These devices manage r/w block by block .A block is defined by the OS as some n bytes ..It could be 512 , 1024 , 2048 or 4096 Bytes …Bigger the block size faster the r/w. Basic unit of a file r/w is a block. Even if a file size is logically 100 bytes , physically it would be a minimum of 1 block .

3.I/O is Stream oriented :-

A stream is defined as a logical producer (input stream) or consumer (output stream) of bits. A stream could be a file or a device like keyboard , monitor , printer etc.. .This stream based I/O has the advantage of rendering a uniform approach to managing data whether to a file or a device. Devices are also treated as files.

Text Stream and Binary stream :-

Text data manages data in a simple format . This means all data is converted to corresponding ASCII codes (one to one) and written to files . Data may be numeric or non numeric . Even numbers are treated this way .

For e.g. 123 would be stored as 0000 0001 0000 0010 0000 0011

The data 123 would occupy 3 bytes .

All reads produce the data correctly by converting back ascii to characters. Numeric data is not distinguished from character type of data. This type of r/w are found in text editors like notepad, Dos Edit .

Binary data : Data is converted into specific binary formats based on some algorithms .

For e.g

Suppose we have an integral data quantity = 123 . Asuming that an int is allocated 2 bytes , this data would be stored in 16 bits as (64+32+16+8+2+1) 0000 0000 0111 1011

r/w converts data appropriately. Numeric data is distinguished from character/string type of data .Floats are managed differently from integral data .This type of r/w are found in data base management softwares.

End of file marker EOF :-

Text files carry an End of file marker (EOF -1 , ascii 26 ] while binary files do not have any such marker . The binary mode files keep track of the end of the file by the number of characters in the directory entry of the file .

Handling Of Newline Character

Text files convert newlines(‘\n’) into a combination of ‘\n’ + ‘\r’ (line feed + carriage return) . Likewise every carriage return – line feed combination is converted into a newline character when a file is read from the disk. No such conversions take place in a binary mode file.

Storage Of Numbers

When a text file is stored to a disk the numbers present in the file are also stored as characters . Therefore they occupy one byte per character. Eg the number 1234 would not occupy 2 bytes as an integer would but it occupies 4 bytes . Thus larger numbers will occupy larger space on disk which is undesirable. However in binary mode numbers are stored in binary format . Hence they will occupy the same space on disk as they will in memory.

FILE pointer FILE *fp

You need a FILE pointer * for a file for all read write operations.

A FILE pointer is a special kind of a pointer to a structure that associates a file with some handler .

Once we have established this handler , we use this in coding and not the file name.

The link between the program and the operating system is a structure called FILE which has been

declared in the header file stdio.h .

always include stdio.h file in disk level input/output programs

When a request is made to the operating system to open

a file what we get back is a pointer to the structure FILE.

FILE fp ; /* fp is a pointer variable which contains the address of the structure FILE */

--

The FILE structure contains the following information :-

· File being used

· Its current size

· Its location in memory

· It contains a character pointer which points to the character that will be read.

Predefined stream pointers :-

C defines 5 predefined FILE pointers

  • stdin a pointer to an input stream (keyboard)
  • stdout a pointer to an output stream(monitor)
  • stderr a pointer to the std error device(monitor)
  • stdprn printer
  • stdaux auxillary port

Opening a file with function fopen( ):-

A call to the function fopen( ) returns a FILE * . Before we can read information from a file or write to a file on a disk we must open it. Opening a file establishes a link between the program and the operating system.

Declaration :

FILE * fopen(const char *filename , const char *fileopenmode );

File Opening Modes

A file can be opened in various modes depending upon our need .

If we need only to read a file it can be opened in the read mode or if we have to write information to a file it can be opened in the write mode and so on.

The different modes available for opening a file are:-

File Operation Text file Binary File

Read (input) “r” or “rt” “rb”

Write(output) “w” or “wt” “wb”

Append(output) “a” or “at” “ab”

Read , write , modify “r+” or “rt+” “rb+”

Write and read

Create the file , then read “w+” or “wt+” “wb+”

Append and read “a+” or “at+” “ab+”

Note :

· Write(output) mode creates file . IF the file already exists, a call to fopen( ) destroys the file

· Append mode adds to the end of an existing file. If file does not exist then the file is created. If it exists then the file is not recreated

· A file opened in binary mode should be manipulated in binary mode only

· Text mode is the default mode . So “r” and “rt” are one and the same

Opening a file :-

FILE *fp ;

fp = fopen(“Filename” , “w”);

Trouble in opening a file

· It is possible that when a request is made for opening a file the request may not be granted for various reasons as follows :

· Wrong path / drive was specified

· OS conventions for filename were violated

· Attempting to open a non existent file for reading

· Hardware problem like lack of disk space

At such times fopen() returns a value NULL (defined in stdio.h as #define NULL 0).So each time a file is to be opened a check is to be made .Did we succeed in opening the file ?

#include

main( )

{

FILE *fp ;

fp = fopen(“Test.c”, “r”);

/*

Test.c is the name of the file to be opened in read mode

check whether file has been opened properly

*/

if ( fp == NULL)

{

printf(“ Unable to open file”);

exit(1);

}

}

Reading / Writing To a File

Several file related functions are available .

fputc( ) write one character to a file

Declaration :- int fputc(int ch , FILE *fp ) :

fputc(ch , fp); /* ch is written to file */

fgetc( ) picks up and returns one character from the file

Declaration :

int fgetc(FILE *fp) ;

ch = fgetc(fp);

fgets( ) picks up a string of n characters from a file and places it in the buffer pointed to by s

Declaration:

char *fgets(char *s, int n, FILE *stream) :

fputs( ) writes a string from the buffer pointed to by s to file

Declaration:

int fputs(const char *s, FILE *stream);

feof( ) Macro that tests if end-of-file has been reached on a stream.

Declaration:

int feof(FILE *stream);

returns 0 if end of file reached , else –1

Handling of binary stream as records :

In a binary file I/O , specific number of bytes of binary data is written to a file .This is called as a record. A record could be a structure type of variable. A record is a collection of related data .This is the human perception.For e.g we may have a product record holding product code , name , rate , qty .We may have a student record holding roll number , name , data of birth and so on.

Read / writes in a binary file :

Functions fread( ) , fwrite( ) are used

fread ( ) : Reads a binary stream into a buffer

Declaration:

size_t fread(void *ptr, size_t size, size_t n, FILE *stream);

Copies size bytes into a buffer pointed to by ptr , n times

fwrite( ) : Writes a binary stream from a buffer to a file

Declaration:

size_t fwrite(void *ptr, size_t size, size_t n, FILE *stream);

Copies size bytes , n times from the buffer pointed to by ptr ,to a file associated with the file handler stream

Record by record navigation :-

The C program distinguishes between one record and another by the size of each record .There is no inter record separator

Random Data access :

The function fseek( ) positions the file pointer in a specific position .

Declaration:

int fseek(FILE *stream, long offset, int whence);

offset : Number of bytes as long

The third argument can be specified as a macro :

SEEK_SET 0 Seeks from beginning of file

SEEK_CUR 1 Seeks from current position

SEEK_END 2 Seeks from end of file

Returns 0 if successful else non zero

Finding out file size and number of records :-

The function ftell( ) returns the byte position of the current file pointer position .When the file pointer is at the end of the file then ftell returns the file size in bytes

Declaration:

long ftell(FILE *stream);

Number of records = filesize / size of each record

Program1 : Create a text file and display its contents

#include

main( )

{

FILE *fp ;

char ch ;

clrscr( ) ;

fp = fopen(“Test.c”, “w+”);

if ( fp == NULL)

{

printf(“Unable to open file “);

exit(1);

}

printf(“Type text Press ^z to save file :- \n”);

while((ch = getchar() ) != EOF )

{

fputc(ch , fp);

}

printf(“\n1 File Saved”);

printf(“\nReading file : TEXT.C \n\n”);

rewind(fp); /* go to the beginning of the file */

while( !feof(fp) )

{

ch = fgetc(fp);

putchar(ch);

}

fclose(fp);

getch();

}

Closing a File :-

A call to the function fclose() flushes all the contents of the buffer to the disk before closing the program .fclose() also disassociates the file pointer and the external name that was established by fopen( ) freeing the file pointer for another file.

Program 2:

/* program to copy the contents of one file to another file */

#include

main()

{

FILE *fs , *ft ;

char ch ;

fs = fopen(“file1” ,”r” );

ft = fopen(“file2” , “w”);

if ( (fs == NULL) || (ft == NULL) )

{

printf(“Unable to open file”);

exit(1);

}

while(! feof(fs) )

{

ch = fgetc(fs);

fputc(ch , fp);

}

fcloseall( ) ;

getch();

}

Program 3 :-

#include

#include

main()

{

FILE *fp ;

char str[80] ;

fp = fopen(“file1” , “w+”);

if ( fp == NULL)

{

printf(“File Creation Error”);

exit( 1 ) ;

}

printf(“\n Enter some lines of text \nPress enter key on a blank line to save \n\n”);

while(1)

{

gets(str);

if(strlen(str) == 0 )

break ;

fputs(str , fp );

fputs(“\n”);

}

printf(“1 File Saved\n”);

rewind(fp);

printf(“\nDisplaying contents of file : FILE1 \n\n”);

while( !feof(fp) )

{

fgets(str , 79 , fp );

puts(str);

}

fclose ( fp ) ;

getch();

}

Formatted I/O fscanf( ) , fprintf( )

For reading and writing of characters, strings ,integers and floats we make use of two functions fscanf() and fprintf() respectively .

Program:

/* program to illustrate the use of fprintf() and fscanf() for writing to and reading from a file */

#include

main()

{

FILE *fp , *ft ;

char name[50] , ans = ‘y’ ;

int marks ;

fp = fopen(“student.dbf” , “w”);

if ( fp == NULL )

{

printf(“\n Unable to open file”);

exit( 1 );

}

while(ans == ‘y’ || ans == ‘Y’ )

{

printf(“\n Enter the name and marks of a student :- “);

scanf(“%s %d”, name , &marks);

fprintf ( fp , “%s%d“ , name , marks);

printf (“\n1 Record Created”);

printf(“\nOne more record ? “);

fflush(stdin);

ans = getchar( );

}

fclose( fp ); //data has been written into file and closed.

ft = fopen(“student.dbf”, ”r”) ;

if ( ft == NULL)

{

printf(“\n Unable to open file”);

exit ( 2 ) ;

}

/* Reading the contents of the file till end of file is encountered and printing it on screen */

while ( !feof ( ft ) )

{

if ( fscanf ( ft , “%s %d” , name , &marks) != EOF )

{

printf(“\n %s %d “ , name , marks);

}

}

fclose ( ft ) ;

getch ( ) ;

}

Reading and Writing To A Binary File Using Structures

#include

#include

struct student

{

char name[10] , address[20] ;

int rollno , std ;

} ;

struct student s ;

main()

{

FILE *fp;

int i , recsize ;

char ans = ‘y’ ;

recsize = sizeof (s) ;

clrscr();

fp = fopen(“Student.dat” , “wb+”) ;

/* file is opened in the binary mode for writing */

if ( fp == NULL)

{

printf(“File creation error”);

exit( 1 ) ;

}

while( ans == ‘y’ || ans == ‘Y’)

{

printf(“\n Enter the name , address , rollno and std :- “);

scanf(“%s%s%d%d” , s.name , s.address , &s.rollno , &s.std ) ;

fwrite(&s , recsize , 1 , fp);

printf(“\n Do you want to enter another record (y/n) ? ”);

fflush(stdin);

ans = getchar( ) ;

}

fseek(fp , 0L , SEEK_SET ) ;

/* Position the file pointer to the beginning of file */

printf(“%10s%10s%10s%10s\n\n” , “Name” , “Address” , “Roll No” , “Std” ) ;

while( !feof(fp) )

{

if ( fread(&s , recsize , 1 , fp) == 1)

{

printf(“%10s%20s%10d%10d” , e.name , e.address , e.rollno , e.std);

}

}

fclose(fp);

getch();

}