You are on page 1of 79

UNIT V

5.0 INTRODUCTION TO STRUCTURES


The basic data types in C are int, float and char. using these data types, we can derive some other data types, the data types that are derived from the basic data types are called derived data types. We have already discussed three of the six derived types: arrays, functions and pointers. In this unit, we discuss the three remaining derived types: structure, union and enumerated. We will also discuss the use of type definition and Bit field. The derived data types are shown in Figure 5.0.

Figure 5.0 Derived Types in C

5.1 STRUCTURES
We have seen that arrays can be used to represent a group of data items that belong to the same type. However in real world, we often deal with entities that are collection of dissimilar data items. Using array variables we cannot store different items under one name. C supports a derived data type known as structure, which is a method for storing data of different types. Structure Definition A structure is a collection of logically related elements, possibly of different types, having a single name. B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 1

Advantages Structures help to organize complex data in a more meaningful way. Being able to manipulate several variables as a single group makes your programs easier to manage. Business data processing uses the concepts of structures in almost every program. Examples, student database and employee database management. Good candidates for structures: Time: year, month, day, hour, minutes, second Complex number: real part, imaginary part Point in a 2-dimensional plane: x axis, y axis 5.2 DEFINITION OF STRUCTURES As variables are defined before they use in the program, structures are also defined and declared before they are used. A structure definition forms a template that may be used to crate structure objects. The variables that make up the structure are called members of the structure. A structure can be defined using three different ways, Tagged Structure Structure Variables Typedef Structure Tagged Structure The structure definition associated with the structure name is referred as tagged structure. It does not create an instance of a structure and does not allocate any memory. The general form or syntax of tagged structure definition is as follows,

struct tag_name { type1 member1; type2 member2; };


B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 2

Where, struct is the keyword which tells the compiler that a structure is being defined. Tag_name is the name of the structure. member1, member2 are called members of the structure. The members are declared within curly braces. The closing brace must end with the semicolon. Example: student details using tagged structure struct student { char name [10]; int roll_number; float avg_marks; };

// no memory is allocated for the structure

Note the following points with respect to above structure definition, struct is the keyword which tells the compiler structure is being defined. student is an identifier representing the structure name (tag_name). name, roll_number and avg_marks are members of a structure and are themselves are not variables. They do not occupy any memory. Memory is not reserved for the structure definition since no variables are associated with the structure definition. The members of the structure do not occupy any memory until they are associated with the structure variables. The declaration of the structure variable takes of the form, struct tag_name var1, var2;

Where, struct is the keyword. Tag_name is the name of the structure. Structure variables are separated by comma, followed by semicolon. We can declare structure variables any where in the program. For the above example the variable declaration as follows, struct student s1; // memory is allocated for the variable now a variable of type struct student (derived type) is created, the memory is allocated for the variable s1. B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 3

The following figure shows the memory organization for the above example.

s1
------ Name ------> < 10 Bytes > <- Roll_Number -> < 2 Bytes > <- Avg_Marks -> < 4 Bytes >

Figure 5.1 Memory map for structure variable The number of bytes allocated for the structure variable is the sum of sizes of the individual members. In the above example the size of s1=16 bytes (10+2+4). Note: Normally, structure definition appears at the beginning of the program file, before any variables or functions defined. Structure Variables Here we are combining both the template declaration and variable declaration in one statement, is referred as structure variables. The syntax of tagged structure is as follows, struct tag_name { type1 member1; type2 member2; } var1, var2; Where, struct is the keyword which tells the compiler that a structure is being defined. tag_name is the name of the structure. member1, member2 are called members of the structure. The members are declared within curly braces. var1, var2 are structure variables that follow curly braces. Here each variable occupies memory. The closing brace must end with the semicolon. Example: student details using structure variables struct student { char name [10]; int roll_number; float avg_marks; } s1; B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 4

Here, name, roll_number and avg_marks are the structure members. s1 is the structure variable, the compiler allocates memory for the variable s1 as shown in Figure 5.1. We can omit the tag name from the structure definition, the following is valid. struct { char name [10]; int roll_number; float avg_marks; } s1, s2; Declares s1 and s2 as structure variables representing two students. This structure definition and declaration is normally not used because we can not declare variables in later stage in the program. Typedefined Structure The structure definition associated with keyword typedef is called typedefined structure. This is the most powerful way of defining the structure. The syntax of typedefined structure is typedef struct { type1 member1; type2 member2; } TYPE_ID; where, typedef is keyword added to the beginning of the definition. struct is the keyword which tells the compiler that a structure is being defined. member1, member2are called fields of the structure. The closing brace must end with type definition name which in turn ends with semicolon. Example: Student details //Structure Definition typedef struct { char name [10]; int roll_number; float avg_marks; } STUDENT; //no memory is allocated for structure /* structure declaration */ STUDENT s1, s2; //memory is allocated for the variables. B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 5

Note: Using typedef it is not possible to declare a variable. But, we can have user defined data type. TYPE_ID can be treated as the new data type. 5.3 INITIALIZATION OF STRUCTURES The rules for structure initialization are similar to the rules for array initialization. The initializers are enclosed in braces and separate by commas. They must match their corresponding types in the structure definition. The syntax is shown below, struct tag_name variable = {value1, value2, valuen}; Structure initialization can be done in any of the following initialization. Initialization along with Structure definition Consider the structure definition for student with three fields name, roll number and average marks. The initialization of variable can be done as shown below, struct student { char name [5]; int roll_number; float avg; } s1= {Ravi, 10, 67.8}; The various members of the structure have the following values. --- name -------------------------> roll_number ------> ------ avg ---------------> R a v i \0 1 0 6 7 . 8

Figure 5.2 Initial Value of S1 Initialization during Structure declaration Consider the structure definition for student with three fields name, roll number and average marks. The initialization of variable can be done as shown below, struct student { char name[5]; int roll_number; struct student s1= {Ravi, 10, 67.8}; B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 6

float avg;

};

The various members of the structure have the values as shown in Figure 5.2. We can also initialize multiple variables using comma between variables. Points to Remember The members of the structure cannot be initialized in the structure definition. For example, struct s { char name [10] ="ravi; int rno; } s1; is invalid. The initial values are assigned to members of the structure on one-to-one basis i.e., the values are assigned to various members in the order specified from the first member. For example, s1= {ravi, 60, 56.7}; is valid. Here, the string ravi will be assigned to the first is assigned to the second member and 56.7 is assigned member. member. 60 to the third

During partial initialization, the values are assigned to members in the order specified and the remaining members are initialized with garbage values. For example, s1= {ravi}; will assign the string ravi to name and the remaining members are initialized to garbage values. However the statement, s1= {40, 67.8}; is invalid, because, without initializing the first member name, we are trying to initialize last two members.

B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 7

During initialization, the number of initializers should not exceed the number of members. It leads to syntax error. For example, s1= {ravi, 45, 78.9, 89}; The compiler issues a syntax error too many initializers

5.4 ACCESSING STRUCTURES


We know that variables can be accessed and manipulates using expressions and operators. On the similar lines, the structure members can be accessed and manipulated. The members of a structure can be accessed by using dot(.) operator. dot (.) operator Structures use a dot (.) operator to refer its elements, also known as period operator. Before dot, there must always be a structure variable. After the dot, there must always be a structure element. The syntax to access the structure members as follows, structure_variable_name. structure_member_name For example, consider the example as shown below, struct student { char name [5]; int roll_number; float avg; }; struct student s1= {Ravi, 10, 67.8}; The members can be accessed using the variables as shown below, s1.name --> refers the string ravi s1.roll_number --> refers the roll_number 10 s1.avg --> refers avg 67.8

B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 8

Arrays with in structures It is also possible to declare an array as a member of structure, like declaring ordinary variables. For example to store marks of a student in three subjects the we can have the following definition of a structure. struct student { char name [5]; int roll_number; int marks [3]; float avg; }; Then the initialization of the array marks done as follows, struct student s1= {ravi, 34, {60,70,80}}; The values of the member marks array are referred as follows, s1.marks [0] --> will refer the 0th element in the marks s1.marks [1] --> will refer the 1st element in the marks s1.marks [2] --> will refer the 2ndt element in the marks The below program illustrates how to define a structure, declare a structure and access the members of the structure.

OUTPUT

B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 9

5.5 STRUCTURE OPERATIONS


Any operation that can be performed on ordinary variables can also be performed on structure members. But, some operations can not be performed on structure variables. The following sections deals with operations that carried on structure and structure members. Copying of structure Variables or members B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 10

Copying of two structure variables is achieved using assignment operator. But, one structure variable can be assigned to another structure variable of the same type. Example, struct student { char name [10]; float avg; } a, b; a=b; //copies b in to a a.avg = b.avg; // copies b average in to a.avg We can not copy the variables of different structure type.

OUTPUT

Comparison of two structure variables or members Two variables of same structure type or dissimilar type is not allowed. B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 11

For example, the following operations are invalid, even though s1 and s2 are of the same type, s1==s2; (or) s1! = s2; invalid: because comparison is not allowed between structure variables. However, the members of two structure variables of same type can be compared the same way as ordinary variables. s1 and s2 are two structures, and then the following operations are valid. Operation s1.member1 == s2.member1 s1.member1 != s2.member1 Meaning Compares member1 of a with member1 of b and return true if they are same, false otherwise. returns if the member1 of a and member1 of b are not same and false otherwise.

Table 5.1 Comparison of Structure Members Arithmetic Operations on Structures The members of a structure are same to any ordinary variable and so any operation that can be performed on a variable can also be performed on structure members. The following operations are valid. Expression ++e.salary e.salary++ &e.salary &e Meaning increments the salary before accessing its value. increments the salary after accessing its value. Access the address if e.salary. Access the beginning address of the structure.

Table 5.2 Arithmetic Operations on Structure Members Note: The arithmetic, relational, logical and other various operations can be performed on individual members of the structures but not on structure variables.

5.6 NESTED STRUCTURES

B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 12

A structure which includes another structure is called nested structure i.e a structure can be used as a member of another structure. The syntax for the nesting of the structure as follows,

struct tag_name1 { type1 member1; . . }; struct tag_name2 { type1 member1; struct tag_name1 var; };
The syntax for accessing members of a nested structure as follows,

outer_structure_variable.innerstructurevariable.membername
Good candidates for nested structures: Student: dob -> day, month, year Employee: allowance -> da, ta, hra Player: tests, one days, T20 Example: Consider the student information name, roll no, DOB and avg. The DOB consists of day, month, and year. It can be defined as shown below, struct data { int day; int month; int year; }; struct student { B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 13

char name [10]; int roll_number; struct data dob; int marks [3]; float avg; } s1; Note that the above structure consists of a member identified by dob whose type is struct data. The members contained in the inner structure namely day, month and year can be referred to as s1.dob.day s1.dob.month s1.dob.year An inner-most member in a structure can be accessed by chaining all the concerned structure variables (from outer-most to inner-most). The memory organization of variable s1 is shown in Figure 5.3.

s1
name 10 bytes roll_number 2 bytes dob day month year 2 bts 2 bts 2 bts marks 6 bytes year 4 bytes

Figure 5.3: Memory organization of nested structure We can nest two structures by using the following syntax, struct tag_name1 struct student { { type1 member1; char name [10]; . int roll_number; . struct data struct tag_name2 { { int day; type1 member1; int month; int year; } dob; } var; int marks [3]; }; In the above definition it is mandatory to initialize avg; float variable to the inner most structure. The members are accessed same way as first method. };

B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 14

Below program illustrates nesting of structures.

OUTPUT

B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 15

5.7 ARRAY OF STRUCTURES


As we have an array of integers, we can have an array of structures also. For example, suppose we want to store the information of class of students, consisting of name, roll_number and marks, A better approach would be to use an array of structures. Array of structures can be declared as follows,

struct tag_name arrayofstructure[size];


After having the above declaration a list of variables of type struct tag_name. Lets take an example, to store the information of 3 students, we can have the following structure definition and declaration, struct student { char name[10]; int rno; float avg; }; struct student s[3]; Defines array called s, which contains three elements. Each element is defined to be of type struct student. For the student details, array of structures can be initialized as follows, struct student s[3]={{ABC,1,56.7},{xyz,2,65.8},{pqr,3,82.4}}; The memory organization of the variables is illustrated in the below Figure,

s
Name rno avg (10bytes) (2 bytes) (4bytes) Name rno avg (10bytes) (2 bytes) (4bytes) B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 16 Name rno avg (10bytes) (2 bytes) (4bytes) s [0]

s [1] s [2]

Figure 5.4: Memory organization of array of structures // program illustrates reading and displaying of student information for a class of students using array of structures #include<stdio.h> struct student { char rollno[10]; char name[20]; gets(s[i].rollno); char branch[10]; printf(" Enter the name:"); char gender; gets(s[i].name); struct birthday printf(" Enter Branch:"); { gets(s[i].branch); int day; printf(" Enter Gender:"); char month[10]; scanf("%c",&s[i].gender); int year; printf(" Entre DOB:"); scanf("%d%s }DOB; %d",&s[i].DOB.day,s[i].DOB.month,&s[i].DOB.year); int sub[3]; printf(" Enter the marks of student:"); float avg; sum=0; }; for(j=0;j<3;j++) { int main() scanf("%d",&s[i].sub[j]); { sum=sum+s[i].sub[j]; int i,n,j,sum=0; } struct student s[10]; s[i].avg=sum/3.0; printf(" Enter how many students are there in the class:"); } scanf("%d",&n); printf("\n******************************************"); printf("\t\t\t\t Enter %d student's details",n); printf("\n\t\t\t Student details:"); for(i=0;i<n;i++) printf("\n******************************************"); { for(i=0;i<n;i++) printf("\n Enter Roll number of %d Student:",i); { fflush(stdin); printf ("\n Student %d:",i+1); printf ("\nRoll number:%s\n Name: %s",s[i].rollno,s[i].name); printf ("\nDOB:%d-%s-%d, s[i].DOB.day,s[i].DOB.month,s[i].DOB.year); printf ("\nAverage=%f", s[i].avg); B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 17 } return 0; }

4.8 STRUCTURES AND POINTERS


The way we can have a pointer pointing to an int, or a pointer pointing to a char, similarly we can have a pointer pointing to a struct. Such pointers are known as structure pointers. To access the values of the members of the structure using pointers we need to perform following things, 1. Declare structure variable: struct tag_name var; 2. Declare a pointer to a structure: struct tag_name *ptr; 3. Store the address of structure variable in structure pointer: 4. Access the members of the structure. Members of the structures can be accessed in following ways: Using De-Reference Operator * and Dot (.) Operator

ptr=&var;

B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 18

If ptr is a pointer to a structure, then the structure itself can be accessed using indirection operator as shown below, struct tag_Name *ptr; // Refers to the whole structure Once the structure pointer is initialized, then each member of the structure can be accessed using dot operator as shown below, (*ptr).structure_member1 (*ptr).structure_member2 Lets take the following segment of code struct student { int rno; char name[10]; float avg; }; struct student s1={101,ABC,78.98}; struct student *ptr; ptr=&s1; Now the members of the structure can be accessed by using the dot operator as shown below, (*ptr).name // Access the name (*ptr).rno // Access roll number (*ptr).avg // Access average Note: The parenthesis to all three expressions is necessary. We should not omit the parenthesis. For example, *ptr .name // invalid way of accessing the member

Using Selection Operator (->) If ptr is a pointer to structure, then the members of the structure can also be accessed using selection operator denoted by ->(which is formed by minus sign and greater than symbol). Using this various members of the structure can be accessed as shown below, ptr -> structrure_member For the above example the members can be accessed as follows, B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 19

ptr - > name // Access the name ptr - > rno // Access roll number ptr - > avg // Access average Remember that on the left hand side of the dot operator, there must always be a structure variable, whereas on the left hand side of -> operator there must be always be a pointer to structure. This method is efficient, preferred over the previous method. s1.rno 101 4001 4003 ptr 4001 5001 Figure 5.5: Memory Representation of Structure Pointer The arrangement of structure variable and pointer to structure in memory is as shown in the Figure 5.5, // C program to read and display student details using pointer to structure s1.name ABC s1.avg 78.98 4013

OUTPUT

B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 20

Structure Containing Pointers #include<stdio.h> We can also contain pointers as members of the structures. The pointer is struct student pointing to a value of the structure member or some other variable. In general to { reduce memory wastage we are using this concept to declare strings as structure char name character pointer. members using[10]; int rno; float *ptr; The below code illustrates pointers as members of structures. }; int main () { struct student s1= {"ABC",405}; float avg=34.5; s1.ptr=&avg; // initializing pointer B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 21 printf ("%f",*s1.ptr); // accessing the value of a variable return 0; }

5.8 STRUCTURES AND FUNCTIONS


We should note that structures are more useful if we are able to pass them to functions and return them. The structures members can be passed to the function in various ways as shown below, 1. BY passing individual members of structure 2. By passing the whole structure 3. By passing structures through pointers Passing Individual Members The first method is to pass each member of the structure as an actual argument of the function call. The actual arguments are treated independently like ordinary variables. // Passing individual structure elements

} OUTPUT B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 22

Explanation Observe that in the declaration of the structure, rno is declared as int, marks are declared as integer array and avg as float. Therefore, when we call the function display using display (s1.rno, s1.marks, &s1.avg); We are passing the structure individual member value, the base address of the array marks and the address of structure member. Thus, this is a mixed of call-a call by reference as well as a call by value. Note: This method is inefficient when the structure size becomes large. A better way would be to pass the entire structure variable at a time. Passing Whole Structure The second method involves passing a copy of the entire structure to the called function. Any changes to structure members within the function are not reflected in the original structure. It is therefore, necessary for the function to return the entire structure back to the calling function. B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 23

The general format of sending a copy of a structure to the called function is: return_type function_name (structure_variable_name); The called function takes the following form: data_type function_name(struct_type tag_name) { return(expression); } The called function must be declared for its type, appropriate to the data type it is expected to return. The structure variable used as the actual argument and the corresponding formal argument in the called function must of the same struct type. The return statement is necessary only when the function is returning some data back to the calling function. The expression may be any simple variable or structure variable or an expression using simple variables. When a function returns a structure, it must be assigned to a structure of identical type in the calling function. The called functions must be declared in the calling function appropriately. // Passing Entire Structure

OUTPUT B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 24

Explanation Note that here the calling of function fun becomes quite compact, fun (s1); then the formal argument in the called function defined as struct type struct student. Returning Structure from a function It is also possible that using return statement we can return structure to the calling function. Here the return type of the function and the return value both must be of type structure. When the function call comes with an assignment to the structure variable, after executing the called function the structure is returned and it is copied into the structure variable in the assignment statement. Below program illustrating function returning structure.

OUTPUT B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 25

Passing Structures through Pointers We have a pointer pointing to a structure. such pointers are known as structure pointers. The third approach employs the concept of pointers to pass the structure as an argument. In this case, the address location of the structure is passed to the called function. The function can access indirectly the entire structure and work on it. Below C program illustrate Passing address of a structure variable.

OUTPUT B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 26

5.9 SELF-REFERENTIAL STRUCTURE


A structure definition which includes at least one member as a pointer to the same structure is known as self-referential structure. Can be linked together to form useful data structures such as lists, queues, stacks and trees. Terminated with a NULL pointer (0). The syntax for using the self referential structure as follows, Struct tag_Name { type1 member1; type2 member2; . Struct tag_Name *next; }; Example, struct node { int data; struct node *next; } n1, n2; Diagram of two self-referential structure objects linked together is shown in below Figure 5.5. B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 27

Figure 5.5 Self Referential Structure Object Linking Here next points to an object of type node referred to as a link ties one node to another node.

5.10 UNIONS
A union is one of the derived data type. Union is a collection of variables referred under a single name. The syntax, declaration and use of union is similar to the structure but its functionality is different. The major distinction between structure and union is, in terms of storage. In structure each member has its own storage location. Whereas all the members of a union use the same location. Although a union may contain many members of different types, it can handle only one member at a time. The general format or syntax of a union definition is as follows,

union tag_name { type1 member1; type2 member2; .. };


Observe the following points while defining a union. union is the keyword which tells the compiler that a union is being defined. member1, member2, are called members (or fields) of the union. The members are declared within curly braces. The compiler allocates a piece of storage that is large enough to hold the largest variable type in the union. There should be semicolon at the end of closing braces. B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 28

A union variable can be declared same way as structure variable. union tag_name var1, var2...; A union definition and variable declaration can be done by using any one on the following Figure 5.6. union u { char c; int i; float f; }; union u a; tagged union variable union Figure 5.6 Types of Union Definitions To access the members of union, the same syntax used to access various members of a structure can be used, by using the dot operator (. ). For above example, we can access various members of the union as shown below, union u { char c; int i; float f; } a; typedef union { char c; int i; float f; } U; U a; typedef union

a.c

a.i

a.f

For the above example, union contains three members, each with a different data type. However, we can use only one of them at a time. a 1001 a.c a.i a.f In the above declaration, the member f requires 4 bytes which is the largest among the members. Above mapping shows how all the three variables share the same address. The size of the structure here is 4 bytes. During accessing, we should make sure that we are accessing the member whose value is currently stored. For example look at the below program, would produces erroneous output (which is machine dependent). 1002 1003 1004

OUTPUT B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 29

In the above program we are initializing all the members of the union at a time, the member which is large enough to hold the largest variable type in the union occupies the memory, here float value is stored in all memory locations of the union.

OUTPUT B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 30

A union creates a storage location that can be used by any one of its members at a time. When a different member is assigned a new value, the new value supersedes the previous members value. The above program illustrates the effective use of union memory locations. We can also create a pointer to a union; the syntax is as follows,

union tag_name *ptr;


union u { char c; int i; float f; }; union u *ptr; B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 31

For the pointer variables, the indirection operator * and dot operator or selection operator -> can be used to access the members. For the above example, using pointer variable ptr, the various members of the union as shown below,

ptr -> c or (*ptr).c ptr.i -> i or (*ptr).i ptr.f -> f or (*ptr).f


structure with in union It also possible union may also contain structures as members of it. The following code illustrates this concept.

OUTPUT B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 32

In the above program we have two structure declarations a and b followed by one union declaration u. Here the members of the union are two structure variables. Now the size of the union is 4 bytes, because the first structure contains two integer members so its size is 4 bytes, and the second structure contains two character members so its size is 2 bytes, therefore the size of the union is 4 bytes and entire memory locations are occupied by the first structure variable.

uu.aa.i uu.bb.x 0000 0000 6501 uu.bb.y 0000 0010 6502 0000 0000 6503

uu.aa.j

0000 0001 6504

512:- Binary representation 0000 0010 MSB 0000 0000 LSB

256:- Binary representation 0000 0010 MSB 0000 0000 LSB

Figure 5.7: Sharing of Union Members

Difference between Array, Structure and Union


Arrays Keyword Structures struct union Unions

B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 33

Definition

An array is a homogeneous collection of data.

A structure is a collection of logically related elements, possibly of different types, having a single name.

A structure is a collection of logically related elements, possibly of different types, having a single name, shares single memory location. union tag_name { type1 member1; type1 member2; }; union tag_name var; Same.

Declaration

data_type array_Name[siz e];

struct tag_name { type1 member1; type1 member2; }; struct tag_name var;

Initializatio n

Accessing

Done by separating list of values with comma (,), specified in Curly braces { }. Accessed by specifying array name with subscript Each array element occupies memory, stored in contigenous locations. Size of the array is depending on the array type and size. sizeof (arr);

Same.

Accessed by specifying structure variablename.membe rname Each member of the structure occupies unique location, stored in contigenous locations. Size of the structure depends on the type of members, adding size of all members. sizeof (st_var);

Accessed by specifying Union variablename.membern ame Memory is allocated by considering the size of largest member. All the members share the common location Size is given by the size of largest member storage. sizeof(un_variable);

Memory Allocation

Size

B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 34

Using pointers

An array elements values can be accessed by using dereferencing operator(*) We can have array of structures or unions. here the array type is structure or union. All elements can be accessed at a time

Structure members can be accessed by using de-referencing operator dot operator and selection operator(->) We can have arrays as a member of structures.

Same as structure.

We can have array as a member of union.

All members can be accessed at a time Nesting of structures is possible. It is possible union with in structure as a member.

Only one member can be accessed at a time. Same. It is possible union may contain structure as a member

Table 5.3: Difference between Array, Structure and Union

5.11 TYPEDEF
C supports a feature known as type definition that allows users to define an identifier that would represent an existing data type. Its purpose is to redefine the name of an existing variable type. The general syntax of the typedef is as follows, typedef data_type IDENTIFIER; Where, typedef is the keyword tells the compiler about the type definition. data_type refers to an existing data type. IDENTIFIER refers the new name given to the data type. Usually, uppercase letters are used to make it clear that we are dealing with a renamed data type

B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 35

Note that using typedef, we are not creating new data types. Instead we are creating only new name for the existing data type. These new data type names are called user-defined data types. Suppose we want to store marks scored in various subjects in variables sub1, sub2 and sub3. These variables can be declared as follows, int sub1, sub2, sub3; Using the user-defined data types, the variables can be declared as shown below, typedef int MARKS; MARKS sub1, sub2, sub3; Advantages Provides a meaningful way of declaring the variables. Increase the readability of the program. A complex declaration can be reduced to short and meaningful declaration. typedef is widely used while dealing with structures.

OUTPUT

typedef with structures using typedef, it is efficient way to define a structure. It can be defined as follows,

B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 36

typedef struct { type1 member1; type2 member2; } TYPE-ID; Following are examples of typedef structure struct employee { char name [30]; int age; float b_sal; }; typedef Struct employee EMP; EMP e1, e2; typedef struct employee { char name [30]; int age; float b_sal; } EMP; EMP e1, e2;

members can be accessed same way as normal structure. But here we are creating new type. For the above example the type name is EMP. typedef can also be used to rename pointer data types as shown below:

typedef struct employee { char name [30]; int age; float bs; } typedef struct employee *PEMP; PEMP p;

The below program illustrates the definition of structure with typedef, declaring variables and accessing members. OUTPUT

B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 37

5.12 INTRODUCTION TO FILES


Reading, processing and writing of data are the three essential functions of a computer program. Most programs take some data as input and display the

B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 38

processed data, often known as result. Unlike other high level languages, C does not have any built-in input/output statements as part of its syntax. A library of functions is supplied to perform these (I/O) operations. The I/O library functions are listed the header file <stdio.h>. You do not need to memorize them, just be familiar with them. The I/O library functions can be classified into two broad categories: Console I/O functions - functions to receive input from keyboard and write output to VDU. File I/O functions hard disk. functions to perform I/O operations on a floppy disk or a

Console I/O Functions Console I/O refers to the operations that occur at the keyboard and screen of the computer. Because input and output to the console is such a common affair, a subsystem of the ANSI I/O file system was created to deal exclusively with console I/O. Technically, these functions direct their operations to the standard input (stdin) and standard output (stdout) of the system. Console I/O functions are further divided into two categories: 1. Formatted console I/O functions printf/scanf. 2. Unformatted console I/O functions getchar, putchar etc. Disadvantages This works fine as long as the data is small. Real-world problems involve large volumes of data and in such situations Console I/O functions pose two major problems, 1. It becomes time consuming to handle large amount of data. 2. Entire data is lost when either the program is terminated or the computer is turned off. At these times it becomes necessary to store the data in a manner that can be later retrieved and displayed. This medium is usually a file on the disk. This chapter discusses how file I/O operations can be performed.

5.13 FILES
A file is an external collection of related data treated as a unit.

B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 39

The primary purpose of a file is to keep record of data. Record is a group of related fields. Field is a group of characters they convey meaning. Files are stored in auxiliary or secondary storage devices. The two common forms of secondary storage are disk (hard disk, CD and DVD) and tape. Each file ends with an end of file (EOF) at a specified byte number, recorded in file structure. A file must first be opened properly before it can be accessed for reading or writing. When a file is opened an object (buffer) is created and a stream is associated with the object.

5.13.1 BUFFER
When the computer reads, the data move from the external device to memory; when it writes, the data move from memory to the external device. This data movement often uses a special work area known as buffer. A buffer is a temporary storage area that holds data while they are being transferred to or from memory. The primary purpose of a buffer is to synchronize the physical devices with a program's need.

5.13.2 FILE NAME


File name is a string of characters that make up a valid filename. Every operating system uses a set of rules for naming its files. When we want to read or write files, we must use the operating system rules when we name a file. The file name may contain two parts, a primary name and an optional period with extension. Example: input.txt program.c

5.13.3 FILE INFORMATION TABLE

B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 40

A program that reads or write files needs to know several pieces of information, such as name of the file, the position of the current character in the file, etc.., C has predefined structure to hold this information. The stdio.h header file defines this file structure; its name is FILE. When we need a file in our program, we declare it using the FILE type.

5.13.4 STREAM
A stream is a general name given to a flow of data. All input and output is performed with streams. A "stream" is a sequence of characters organized into lines. Each line consists of zero or more characters and ends with the "newline" character. ANSI C standards specify that the system must support lines that are at least 254 characters in length (including the new line character). A stream can be associated with a physical device, terminal, or with the file stored in memory. The following Figure 5.8 illustrates the data flow between external device(c Program), buffer and file. //C program .. Buffer abcdefg Stream abcdefg File Figure: 5.8 data flow Text and binary Streams C uses two types of streams: text and binary. A text stream consists of a sequence of characters divided into lines with each line terminated by a new line (\n). A binary stream consists of sequence of data values such as integer, real, or complex using their memory representation. System Created Streams B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 41

Standard input stream is called "stdin" and is normally connected to the keyboard Standard output stream is called "stdout" and is normally connected to the display screen. Standard error stream is called "stderr" and is also normally connected to the screen.

5.14 STREAM FILE PROCESSING


A file exists as an independent entity with a name known to the O.S. A stream is an entity created by the program. To use a file in our program, we must associate the programs stream name with the file name. In general, there are four steps to processing a file. 1. Create a stream 2. Open a file 3. Process the file (read or write data) 4. Close file Creating a Stream We can create a stream when we declare it. The declaration uses the FILE type as shown below, FILE *fp; The FILE type is a structure that contains the information needed for reading and writing a file, fp is a pointer to the stream. Opening File Once stream has been created, we can ready to associate to a file. In the next section we will discuss in detail. Closing the Stream When file processing is complete, we close the file. After closing the file the stream is no longer available.

5.15 STANDARD LIBRARY I/O FUNCTIONS


B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 42

C includes many standard functions to input data from the keyword and output data to the monitor. For these functions, the stream that connects our programs to the terminal is automatically created by the system and we do not have to do anything more. The stdio.h header file contains several different input/output functions declarations. These are grouped in to eight different categories, as shown in Figure 5.9.

Figure 5.9 Categories of I/O functions File Open and Close In this section we discuss the C functions to open and close streams. File Open (fopen) B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 43

The function that prepares a file for processing is fopen. It does two things: first, it makes the connection between the physical file and the file stream in the program. Second, it creates a program file structure to store the information needed to process the file as shown in Figure 5.10. C Program #include<stdio.h> void main () { .} stream Buffer abcdefghijklmnopqrstu vwxyz

stream File Structure 199 1 10212 2 10200 3 .. File Figure 5.10 File open operations File Structure Some of the fields of file structure are 1) int count: counts bytes left in buffer. 2) char *ptr: pointer to the current buffer position. 3) char *base: pointer to buffer beginning. To open a file, we need to specify the physical filename and its mode. Syntax, fopen (filename, mode); The file mode is a string that tells C compiler how we intend to use the file: read existing file, write a new file or append to a file. Successfully opening a file returns a pointer to (i.e., the address of) a file structure. The actual contents of the FILE are hidden from our view. All we need to know is that we can store the address of the file structure and use it to read or write the file. B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 44 abcdefghijklmnopqrstu vwxyz

The statement:

fptr1 = fopen (mydata", "r);

Would open the file mydata for input (reading). The statement: fptr2 = fopen ("results", "w); Would open the file results for output (writing). Once the files are open, they stay open until you close them or end the program (which will close all files.) File Mode When we open a file, we explicitly define its mode. The mode shows how we will use the file: for reading, for writing, or for appending. r (read) mode The read mode (r) opens an existing file for reading. When a file is opened in this mode, the file marker is positioned at the beginning of the file (first character). The file marker is a logical element in the file structure that keeps track of our current position in the file. The file must already exist: if it does not, NULL is returned as an error. Files opened for reading are shown in Figure 5.11. If we try to write a file opened in read mode, we get an error message. Syntax fp=fopen (filename, r);

w (write) mode The write mode (w) opens for writing. If the file doesnt exist, it is created. IF it is already exists, it is opened and all its data are erased; the file marker is positioned at the beginning of the file (first character) It is an error to try to read from a file opened in write mode. A file opened for writing is shown in figure 5.11. Syntax fp=fopen (filename, w);

a (append) mode The append mode (a) also opens an existing for writing. Instead of creating a new file, however, the writing starts after the last character; that is new data is added, or appended, at the end of the file. IF the file doesnt exist, it is created and opened. In this case, the writing will start at the beginning of the file; File opened in append mode are shown in Figure 5.11. B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 45

Syntax

fp=fopen (filename, a);

r+ (read and write) mode In this mode file is opened for both reading and writing the data. If a file does not exist then NULL, is returned. Syntax: fp=fopen (filename, r+); w+ (read and write) mode In this mode file is opened for both writing and reading the data. If a file already exists its contents erased. If a file does not exist then new file created. Syntax: fp=fopen (filename, w+); a+ (append and read) mode In this mode file is opened for reading the data as well as data can be added at the end. Syntax: fp=fopen (filename, a+);

Figure 5.11 File Opening Modes The above figure shows the file marker position in different modes.

File Close (fclose) Closing a file ensures that all outstanding information associated with the file is flushed out from the buffers and all links to the file are broken. B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 46

Another instance where we have to close a file is to reopen the same file in a different mode. The I/O library supports the following function to do this: fclose (file_pointer); Where fp is the file pointer returned by the call to fopen (). fclose () returns 0 on success (or) -1 on error. Once a file is closed, its file pointer can be reused for another file.

5.15 FORMATED I/O FUNCTIONS


B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 47

We have already familiar with two formatting functions scanf and printf. These two functions can be used only with the keyboard and monitor. The C library defines two more general functions, fscanf and fprintf, that can be used with any txt stream. Formatted Output with printf () This function provides for formatted output to the screen. The syntax is: printf (format string, var1, var2 ); The format string includes a listing of the data types of the variables to be output and, optionally, some text and control character(s). Example: float a=10.5; int b=15; printf (You entered %f and %d \n, a, b); Format Conversion Specifiers d -- displays a decimal (base 10) integer l -- used with other Specifiers to indicate a "long" e -- displays a floating point value in exponential notation f -- displays a floating point value g -- displays a number in either "e" or "f" format c -- displays a single character s -- displays a string of characters Formatted Input with scanf () This function provides for formatted input from the keyboard. The syntax is: scanf ( format string , &var1, &var2, ) ; The format string is a listing of the data types of the variables to be input and the & in front of each variable name tells the system Where to store the value that is input. It provides the address for the variable. B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 48

Example: float a; int b; scanf (%f %d, &a, &b); Reading From Files: fscanf () The general format of fscanf() is, fscanf (stream_pointer,format string, list); The first argument is the stream pointer, is the pointer to the streams that has been declared and associated with a text file. Remaining is same as scanf function arguments. The following example illustrates the use of an input stream. int a, b; FILE *fptr1; fptr1 = fopen (mydata", "r); fscanf (fptr1, "%d %d", &a, &b); The fscanf function would read values from the file "pointed" to by fptr1 and assign those values to a and b. The only difference between scanf and fscanf is that scanf reads data from the stdin (input stream) and fscanf reads input from a user specified stream(stdin or file). The following example illustrates how to read data from keyboard using fscanf, fscanf (stdin,%d, &a); End of File The end-of-file indicator informs the program when there are no more data (no more bytes) to be processed. There are a number of ways to test for the end-offile condition. Another way is to use the value returned by the fscanf function: The following example illustrates testing of end of file.

B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 49

Writing To Files: fprintf () Can handle a group of mixed data simultaneously. The first argument of these functions is a file pointer which specifies the file to be used. B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 50

The general form of fprintf is fprintf (stream_pointer, format string, list); Where stream_pointer is a file pointer associated with a file that has been opened for writing. The format string contains output specifications for the items in the list. The list may include variables, constants and strings. The following example illustrates the use of an Output stream. int a = 5, b = 20; FILE *fptr2; fptr2 = fopen (results", "w); fprintf (fptr2, "%d %d\n", a, b) ; The fprintf functions would write the values stored in a and b to the file "pointed" to by fptr2. fprintf function works like printf except that it specifies the file in which the data will be displayed. The file can be standard output (stdout) or standard error (stderr) also. Example, fprintf (stdout,%d,45); displays 45 on Monitor.

B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 51

// OUTPUT

// Contents of File testdata.txt

B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 52

5.16 CHARACTER I/O FUNCTIONS


Character input functions read one character at a time from a text stream. Character output functions write one character at the time to a text stream. These functions can be divided into two categories, 1. Terminal Character I/O 2. Terminal and File Character I/O

5.16.1 TERMINAL CHARACTER I/O


C declares a set of character input/output functions that can only be used with the standard streams: standard input (stdin), standard output (stdout). Read a Character: getchar () This function is to read exactly one character from the keyboard; it reads the next character from the standard input stream. Syntax for using getchar () function is as follows,

ch =getchar ();
Its return value is integer. Up on successful reading returns the ASCII value of character. If there is an error returns EOF. Write a Character: putchar () This function provides for printing exactly one character to the Monitor. Syntax for using putchar () function is as follows,

ch =getchar (); /* input a character from keyboard*/ putchar (ch); /* display character on the Monitor */

Its return value is integer. Up on successful writing returns the ASCII value of character. If there is an error returns EOF.

B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 53

5.16.2 TERMINAL AND FILE CHARACTER I/O


The terminal character input/output functions are designed for convenience; we dont need to specify the stream. Here, we can use a more general set of functions that can be used with both the standard streams and a file. These functions require an argument that specifies the stream associated with a terminal device or a file. When used with a terminal device, the streams are declared and opened by the system, the standard input stream (stdin) for the keyword and standard output stream (stdout) for the monitor. When used with a file, we need to explicitly declare the stream, it is our responsibility to open the stream and associate with the file. Read a Character: getc () and fgetc () The getc functions read the next character from the file stream, which can be a used-defined stream or stdin, and converts it in to an integer. This function has one argument which is the file pointer declared as FILE. If the read detects an end of file, the function returns EOF, EOF is also returned if any error occurs. The functionality of getc/fgetc same. Syntax for using getc/fgetc, getc (fp); fgetc (fp); Example, char ch; ch = getc (stdin); ch =fgetc (fileptr); Write a Character: putc () and fputc () The putc functions write a character to the file stream specified which can be a user-defined stream, stdout, or stderr. The functionality of putc/ fputc same. For fputc, the function takes two arguments. The first parameter is the character to be written and the second parameter is the file, The second parameter is the file pointer declared as FILE. If the character is successfully written, the function returns it. If any error occurs, it returns EOF. B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 54 /* input from keyboard */ /* input from a file */

Syntax, putc (char, *fp); fputc (char, *fp); Example, char ch; ch = getc (stdin); putc (ch, stdout); putc (ch, outfileptr); /* input from keyboard */ /* output to the screen */ /*output to a file */

B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 55

B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 56

Contents of input.txt file

Contents of output.txt file

5.17 LINE I/O FUNCTIONS


Reading Strings: gets () and fgets () The gets and fgets function take a line (terminated by a new line) from the input stream and make a null-terminated string out of it. These are sometimes called line-to-string input function. gets () gets function reads a string from terminal, reading is terminated by new line.

B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 57

The newline (\n) indicates the end of the string, it is replaced by null (\0) character in the memory by the function gets () as shown in Figure 5.12. The source of data for the gets function is standard input. gets function takes only one parameter, the name of the string, its syntax is as follows, gets (string_name);

Figure 5.12 Working of gets/fgets functions fgets () fgets function reads a string from file or keyboard. It reads characters from the specified file until a new line character has been read or until n-1 characters has been read, whichever occurs first. The function automatically places null character at the end as shown in Figure 5.12. The source of data for fgets can be a file or standard input. The general format, fgets (string, length, fp); First argument is name of the string in which the read data from the file is to be placed. Second argument is the length of the string to be read and last argument is the file pointer. fgets also reads data from terminal. Below example illustrates this, fgets (str, 10, stdin); B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 58

B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 59

Output:

Contents of getdata.txt file

Writing Strings: puts () and fputs () puts/fputs functions take a null-terminated string from memory and write it to a file or the monitor. These are sometimes called string-to-line output functions. puts () puts function writes a string to terminal, writing is terminated by null character. the null character is replaced with a new line inputs as shown in Figure 5.13. puts function takes only one parameter, the name of the string, its syntax is as follows, puts (string_name); fputs () fputs function writes a string to a file or monitor. B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 60

Characters stored in the string are written to the file identified by fileptr until the null character is reached. The null character is not written to the file as shown in Figure 5.13. The general format forms are fputs (string, fp); First argument is address of the string in which the read data is to be placed. Second argument is the file pointer.

Figure 5.13 Working of puts/fputs Functions

B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 61

// output

// Contents of file writedat.txt

B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 62

5.18 STRING/DATA CONVERSION FUNCTIONS


A common set of applications format data by either converting a sequence of characters into corresponding data types or vice versa. C already has set of data conversion functions created for scanf and printf. The C standard also includes two sets of memory formatting functions: sscanf and sprintf. String to Data Convertion: sscanf () The string scan function is called sscanf. sscanf is a one-to-many function. It splits one string into many variables. This function scans a string through the data were coming from a file. Just like fscanf, it requires a format string to provide the formatting parameters for the data. Instead of reading these data from the keyboard, we can also read from a string stored in memory using sscanf (). Syntax, sscanf (string, control string, variables); The first argument is the string, which contains the data to be scanned. The second is the control string consisting of format Specifiers. Variables, it is a list of variables in to which formatted data is copied. Its return value is integer. If the sscanf () is successful it returns how many variables formatted. The error is specified with EOF.

Figure 5.14 Working of sscanf Function Example, sscanf (hyd 45 67.89, %s %d %f, name, &a, &b); Would result in name=hyd, a=45 and b=67.890000 B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 63

Data to String Convertion sprintf () The string print function is sprintf, follows the rules of fprintf. Rather than sending the data to a file. however, it simply writes them to a string. When all data have been formatted to the string, a terminating null character is added to make the result a valid string. If an error is detected, sprintf returns any negative value or EOF. If the formatting is successful, it returns number of characters formatted.

Figure 5.15 Working of sscanf Function Syntax, sprintf (string, control string, variables); The first argument is the string, which contains the data to written. The second is the control string consisting of format Specifiers. Variables, it is a list of variables in to which formatted data is copied. Example, sprintf (str,%s %d %f, name, a, b); will result in str =name + a + b.

B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 64

5.19 TEXT FILES AND BINARY FILES


Text File A text file is the one where data is stored as a stream of characters that can be processed sequentially. In the text format, data are organized into lines terminated by newline character. The text files are in human readable form and they can be created and read using any text editor. Since text files process only characters, they can read or write only one character at a time. A new line may be converted to carriage return and line feed character. Figure 5.16 shows the data transfer in text file.

B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 65

Figure 5.16 Reading and Writing Text Files Because of these translations, the number of characters written / read may not be the same as the number of characters written / read on the external device. Therefore, there may not be a one to one relationship between the characters written / read into the file and those stored on the external devices. For example, the data 2345 requires 4 bytes with each character occupying exactly one byte. A text file cannot contain integers, floating point numbers etc. converted to their character equivalent formats. Binary File A binary file is the one where data is stored on the disk in the same way as it is represented in the computer memory. The binary files are not in human readable form and they can be created and read only by specific programs written for them. The binary data stored in the file cannot be read using any of the text editors.

Figure 5.17 Block Input and Output For example, the data 2345 takes 2 bytes of memory and is stored as 0 x 0929 i.e., 0 x 09 is stored as one byte and 0 x 29 is stored as other byte. The number of characters written / read is same as the number of characters written / read on the external device. Therefore, there is one to one relationship between the characters written / read into the file and those stored on the external devices.

B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 66

Differences between Text File and Binary File The differences between text file and binary file are as shown in Table 5.4. The following Figure 5.18 illustrates the storage difference between text file and binary file.

Figure 5.18 Binary and Text Files Text File 1. Human readable format. Binary File 1. Not in human readable format.

2. Data is stored as lines of characters 2. Data is stored on the disk in the with each line terminated by / n which may same way as it is represented in the be translated into carriage return + line computer memory. feed. 3. Translation of new line character to 3. No translation of any type. carriage return + line feed. 4. Data can be read using any of the text 4. Data can be read only by specific editors. programs written for them. 5. The number of characters written / read may not be the same as the number of characters written/read on the external device such as disk. 6. There may not be a one to- one relationship between the characters written / read into the file and those stored on the external devices. 5. The number of characters written / read is same as the number of characters written / read on the external device such as disk. 6. There is one to one relationship between the characters written / read into the file and those stored on the external devices.

7. The data 2345 requires 4 bytes with 7. The data 2345 requires 2 bytes each character requiring one byte. So, it and stored as 0x0929. The data is stored as 0x 32, 0x 33, and 0 x 34, 0 x 2345 is requiring 2 bytes. 35 (ASCII values) thus requiring 4 bytes. Table 5.4 Differences between Text File and Binary File B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 67

Opening Binary Files The basic operation is unchanged for binary files-only the mode changes. Different modes of operation of binary file are illustrated in Table 5.5. Mode wb Meaning This mode opens a binary file in write mode. Example: fp=fopen (data.dat,wb); This mode opens a binary file in read mode. rb Example: fp=fopen (data.dat,rb); This mode opens a binary file in append mode. Example: fp=fopen (data.dat,ab); This mode opens/creates a binary file in write and read mode. Example: fp=fopen (data.dat,w+b); This mode opens a pre-existing binary file in read and write mode. Example: fp=fopen (data.dat,r+b); a+b This mode opens/creates a binary file in append mode. Example: fp=fopen (data.dat,a+b); Table 5.5 Binary Modes of Opened File Just like text files, binary files must be closed when they are not needed anymore using fclose ().

ab

w+b

r+b

5.19 BLOCK I/O FUNCTIONS


C language uses the block input and output functions to read and write data to binary files. As we know that data are stored in memory in the form of 0s and 1s. When we read and write the binary files, the data are transferred just as they are found in memory and hence there are no format conversions. The block read function is file read(fread). The block write function is file write (fwrite). File Read: fread () B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 68

This function reads a specified number of bytes from a binary file and places them into memory at the specified location. This function declaration is as follows, int fread (void *pInArea, int elementsize, int count, FILE *sp); The first parameter, pInArea, is a pointer to the input area in memory. The data read from the file should be stored in memory. For this purpose, it is required to allocate the sufficient memory and address of the first byte is stored in pInArea. We say that pInArea now points to buffer. The next two elements, elementSize and count, are multiplied to determine how much data are to be transferred. The size is normally specified using the sizeof operator and the count is normally one when reading structures. The last argument is the pointer to the file we want to read from. This function returns the number of items read. If no items have been read or when error has occurred or EOF encountered, the function returns 0. File read expects a pointer to the input area, which is usually a structure. This is because binary files are most often used to store structures. Figure 5.19 is an example of a file read that reads data into an array of integers. When fread is called, it transfers the next three integers from the file to the array, inArea.

Figure 5.19 File Read Operation File Write: fwrite () B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 69

This function writes specified number of items to a binary file. This function declaration is as follows, int fwrite (void *pInArea, int elementsize, int count, FILE *sp) The parameters for file write correspond exactly to the parameters for the file read function. Figure 5.20 shows the write operation that parallels the read in Figure 5.19.

Figure 5.20 File Write Operation

5.20 FILE POSITIONING FUNCTIONS


File positioning functions have two uses. First, for randomly processing data in disk files, we need to position the file to read the desired data. Second, we can use the positioning functions to change a files state. Thus, we can change the state of the file pointer using one of the positioning functions. There three file position functions, tell location rewind file file seek Current Location: ftell () B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 70

The ftell function reports the current position of the file marker in the file, relative to the beginning of the file. ftell () takes a file pointer and returns a number of type long integer, that corresponds to the current position. Here the return type is long integer because many files have more than 32,767 bytes. The operation ftell is graphically shown in Figure 5.21. The syntax of ftell function as follows, n= ftell(fp); n would give the relative offset of the current position. This means that n bytes have already been read (or written). If ftell encounters an error, it returns -1. Let us consider the following statement, n=ftell (fp);

Figure 5.21 Working of ftell Function The above Figure 5.21 illustrates the working of ftell, it returns 16, and the current offset value. The primary purpose of ftell is to provide a data address (offset) that can be used in a file seek. It is especially helpful when we are dealing with text file for which we cannot calculate the position of data.

Rewind File: rewind () B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 71

The rewind function simply sets the file position indicator to the beginning of the file as shown in Figure 5.22. This function helps us in reading a file more than once, without having to close and open the file. Its common use is to change a work from a write state to a read state. However, that to read and write a file with only one open, we must open it in update mode w+. Syntax to use rewind function is as follows, rewind (fp); Example: rewind (fp); n=ftell (fp); Would assign 0 to n because the file position has been set to the start of the file by rewind.

Figure 5.22 Working of ftell Function Set Position: fseek () fseek () function is used to move the file position to a desired location within the file. B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 72

It takes the following form: fseek (file_ptr, offset, position); file_ptr is a pointer to the file concerned, offset is a number or variable of type long, and position is an integer number. The offset specifies the number of positions to be moved from the location specified by position. The position can take one of the following three values: Value 0 1 2 Meaning beginning of file. Current position. End of file.

The offset may be positive, meaning move forwards, or negative, meaning move backwards. The following Table 5.6 illustrate operations of the fseek() function: Statement fseek(fp,0L,0); fseek(fp,0L,1); fseek(fp,0L,2); fseek(fp,m,0) fseek(fp,m,1); fseek(fp,-m,1); fseek(fp,-m,2); Meaning go to the beginning. stay at the current position. go to the end of the file, past the last character of the file. move to (m+1) th byte in the file. go forward by m bytes. go backward by m bytes from the current position. go backward by m bytes from the end. (positions the file to the character from the end.)

Table 5.6 Operations of the fseek function When the operation is successful, fseek returns a zero. If we attempt to move the file pointer beyond the file boundaries, an error occurs and fseek returns -1.

B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 73

B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 74

// contents of input.txt

B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 75

// output

5.21 FILE STATUS FUNCTIONS


C provides functions for error handling during I/O operations. Typical error situations include: Trying to read beyond the end-of-file mark. Device overflow. Trying to use a file that has not been opened. Trying to perform an operation on a file, when the file is opened for another type of operation. Opening a file with an invalid filename. Attempting to write to a write-protected file. We have two status-inquiry library functions, feof () and ferror () that can help us detect I/O errors in the files. Test End of Files: feof () The feof function can be used to test for an end of file condition. It takes a FILE pointer as its only argument.If all data have been read, the function returns a nonzero (positive value) and returns zero (false) otherwise. It takes of the following form, n=feof (fp); B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 76

If fp is a pointer to file that has just been opened for reading, then the statement if (feof (fp)) printf (End of data.\n); Would display the message End of data on reaching the end of file condition. Test Error: ferror () The ferror function reports the status of the file indicated. Error can be created for many reasons, such as trying to read a file in the write state. It takes of the following form. n=ferror (fp); It also takes a FILE pointer as its argument and returns a non zero integer if an error has been detected up to that point, during processing. Otherwise, it returns zero. The statement if(ferror(fp)!=0) printf (An error has occurred.\n); Would print the error message, if the reading is not successful. However, that testing for an error not reset the error condition. Once a file enters the error state. It can only return to a read or write state by calling clear error function: clearerr. It takes of the form: clearerr (fp); // clears the error information

5.22 COMMAND LINE ARGUMENTS


Command line arguments are parameters supplied to a program, when the program is invoked. C language provides a way to connect to the arguments on the command line needed for the execution of the program. During execution, arguments can be passed to the main () function through command-line arguments. The first parameter treated as name of the file.

B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 77

In order to access the command-line arguments, the main function has a prototype as shown below, int main (int argc, char* argv []) The first parameter argc stands for the argument count, which is of integer data type. Its value is the number of arguments in the command line that was used to execute the program. The second parameter argv stands for the argument vector. It is an array of pointers to the character data type. The program name is the first parameter on the command line, which is argv [0]. // C program illustrates Command Line Arguments #include<stdio.h> int main (int argc, char *argv []) int j; printf (The name of the program is %s, argv[0]); printf (The total number of arguments are: %d, argc); for (j=1; j<=argc; j++) printf (\n argument %d is %s, j, argv[j]); return 0; OUTPUT: C:\tc\bin\>test one two three The name of the program is test The total number of arguments are:4 argument 1 is one argument 2 is two argument 3 is three } {

B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 78

ASSIGNMENT V
1. (a) How does a structure differ from an array? (b) Write a C program using structure to read and print the students records of a class with the following members. i. Field Name Data Type ii. name string iii. reg no integer iv. Major string v. result string 2. Define Structure and write the general format for declaring and accessing structure members with an example. 3. a) Distinguish between text mode and binary mode operation of a file. b) Write short notes on Block I/O Functions 4. What are the file I/O functions in C. Give a brief note about the task performed by each function? 5. Explain the following operations a. b. c. d. e. fseek() ftell() rewind() ferror() feof()

6. Write the syntax for opening a file and closing a file. Explain different modes of operation of a file.

B.V.RAJESH, ASSISTANT PROFESSOR, DEPARTMENT OF IT, SNIST PNO: 79

You might also like