Structures:: C&Dsforimca Unit-5 (Structures and File Management) Vvit
Structures:: C&Dsforimca Unit-5 (Structures and File Management) Vvit
Structures:
Structures in C are constructed data types (user defined data types) which are formed by
packing the data of different data types that already exist.
Once the new data type is created, variables of its kind can be declared and used.
A structure is a convenient way to handle a group of logically related data.
General Format:
struct tag_name
{
data_type1 member1;
data_type2 member2;
data_type3 member3;
-
-
};
Note:
• In general structures are defined globally (at start of program) to make them available in
all function, but they can also be defined locally in a function.
• The structure can be renamed using typedef to have convenient name for the new data
type created instead of using combination of struct and tag_name. The above structure
can be given a new in the following way.
typedef struct student STUDENT;
Declaring variables to structures: Once a structure is declared, variables of its kind can be
created using its name.
The variables for the above structure student can be declared in the following way.
struct student s1,s2,s3;
or
STUDENT s1,s2,s3; (STUDENT is defined using typedef earlier)
Accessing members of structure can be done using the member-operator ‘.’ which is also called
dot operator (or period operator).
b1.page_count b1.price
To read the book title we have a statement like this:
gets(b1.title);
To read page_count and price:
scanf(“%d%f”, &b1.page_count, &b1.price);
To display value:
printf(“ %d, %f, %s”,b1.page_count, b1.price, b1.title);
The structure variables can be initialized while they are declared in the following way.
Note:
• We cannot initialize individual members inside the structure template (definition).
• The order of values enclosed in braces must match the order of members in the structure
definition.
• It is permitted to have a partial initialization. We can initialize only first few members
Arrays Vs Structures
Both arrays and structures are classified as structured data types as they provide a mechanism
that enable us to access and manipulate data in a relatively easy manner. But they differ in a
number of ways.
1. An array is a collection of related data of same type. Structure can have elements of
different types.
2. An array behaves like a built-in data type. All we have to declare an array variable and
use it. But in the case of a structure, first we have to design and declare a data structure
before the variables of that type are declared and used.
Pointer to Structures:
Pointers also can be declared for the structures once they are defined.
struct address
{
char street[30], city[30];
int pin;
}*p1;
struct address *p2;
In the above case 2 pointers are declared one while defining the structure and other after
declaring the structure. Both are valid. The members of the structure can accessed via the
pointers in the flowing way.
(*p1).pin; //this is called indirection notation
p1-> pin; //this is called selection notation
The ‘->’ operator is called as arrow-operator.
Arrays of Structure:
We can declare an array of structures, each element of the array representing a structure variable.
Eg: Program to illustrate the use of array of structures.
#include<stdio.h>
struct player
{
char name[30];
int score; //to store the current score
int prev_scores[3]; //to store the scores of the batsmen in previous 3 matches, this
illustrates that we
//can declare an array as a data member
};
typedef struct player PLAYER;
void main()
{
int i,j,team_score=0;
float avg;
PLAYER team[11]; //declare an array structure to represent 11 member team
for(i=0;i<11;i++)
{
printf("Enter the name of player %d: ",i+1);
gets(team[i].name);
printf("\nEnter the scores in previous 3 innings");
scanf("%d%d%d",&team[i].prev_scores[0],
&team[i].prev_scores[1],&team[i].prev_scores[2]); //accessing members of type arrays
printf("\nEnter the score in current match: ");
scanf("%d",&team[i].score);
team_score+=team[i].score;
}
avg=(float)team_score/11;
printf("\n\nThe total score of the team is %d", team_score);
printf("\n\nThe average score a player in team is %f", avg);
getch();
}
Nested Structures:
Nesting of structures is permitted in C. The data member of a structure can also be a
variable of structure. Nested structure definition can be done different ways as follows:
struct timestamp
{
struct time struct timestamp
{ {
int hrs; struct
int min; {
int sec; int hrs,min,sec;
}t1; //it is compulsory to declare variable here }t1;
int day, month, year; int day, month, year;
}; };
We can define the time structure independently and the use it while defining timestamp. This
way we use time structure independently as well. In both the above cases, we cannot use time
independently, we only access it as a part of timestamp.
struct time
{
int hrs;
int min;
int sec;
};
struct timestamp
{
struct time t1;
int day, month, year;
};
//declaring variable
struct timestamp ts1;
//accessing members
ts1.day, ts1.month
ts1.time.hrs, ts1.time.min //we use 2 dot operators to access inner members of nested structures
• Both call by value and call reference is possible. Pointer to structures can be used in
function definition to achieve call by reference.
• A structure variable can also be returned from a function using return statement provided
the return type is declared as of type structure.
Please refer to lab cycle 11 for example
Unions
Union is the concept borrowed from structures and therefore follows same syntax as
structures. The major distinction between structure and a union is in terms of storage. In structure
each member has its own storage location, whereas in union all members share a same memory
location.
Although a union may contain many members of different types, it can handle only one
member at a time.
Unions can be declared using the keyword union:
union xyz
{
int x;
float y;
char z;
}v1;
The above union xyz contains 3 members each of different type. When the variable v1 is
declared it is allocated only one memory location, so that v1 can stores any one of the members
at a given point of time. The amount of memory allocated will be equal to the largest variable
type in the union which is 4 (for float type) in the above case.
Accessing members of union can done using dot operator similar to structures.
v1.x;
v1.y;
Union allows initializing but can initialize only first member.
union xyz v2={34}; //v2.x is initialized to 34
union xyz v3={34.6}; //invalid statement because first member is of type int and cannot assign float
Bit Fields
Most generally, we use integer fields of size 16 bits to store data. And there will be many
occasions where we require much less than 16 bits; thereby we waste the memory. C permits to
use small bit fields to hold data items and thereby to pack several data items in a word of
memory.
A bit field is a set of adjacent bits whose size can be from 1 to 16 bits on length. A word
can therefore be divided into a number of bit fields. The name and size of bit fields are declared
using structure.
Eg:
struct personal
{
unsigned id : 5; //lets assumes the id is always less than 30
unsigned gender : 1;
unsigned age : 6; //let use assume retirement of emp is 60 and no value is greater than 60
unsigned m_status : 1;
unsigned : 3;
}emp;
This defines a variable emp with five fields. The range of each field is as follows:
id 5 0 - 31
gender 1 0 or 1
age 7 0 -63
m_status 1 0 or 1
Once the bit fields are defined, they can be used just as we do use structure members.
emp.gender=1;
emp.id=25;
Point to be noted:
1. The first field will always start with the first bit of the word.
2. A bit field cannot overlap integer boundaries. i.e. the sum of lengths of all bit fields in a
structures should not be more than size of word (16). In case if it is more, the overlapping
field is automatically forced to the beginning of the next word.
3. There can be unnamed fields declaring the size. (last field in previous case is unnamed).
These fields are just used to fill the gap and not used to store logical data. These fields
provide padding within the word.
4. There can be unused bits in a word.
5. We cannot take the address of bit field’s variable. Therefore we cannot declare pointers
or use them in scanf function.
6. Bit fields cannot be arrayed.
7. Bit fields should be assigned values that are within the range of their size.
File Management in C
Reading from key board and writing to a screen (terminal) may have problems while
dealing with large amount of data. It becomes cumbersome and time consuming to handle large
amount of data from terminals. More over data is lost when either program is terminated or the
computer is switched off.
Files can be used to store the data persistently (permanently). File are stored are stored
on disk and can be used whenever needed. Data stored in files will exist even after terminating
the program or switching off the computer.
The basic file operations supported by C are:
Naming a file
Opening a file
Reading data from file
Writing data to a file (either replacing or appending)
Closing a file.
C has rich set of in built functions (Standard Library functions) to perform the different
operations of file. Few of them are listed here:
fopen() Creates a new file for use. (or) Opens a existing file for use.
getc() Reads a char from the file and sets the position to next character
putc() Writes a char to the file and sets the position to next character
fprintf() Writes a set of data values to a file (also sets position accordingly)
Filename is a string of characters that make up a valid filename. A filename may contain 2 parts,
a primary name and an optional period with extension. If the file does not exist in the current
working directory of the C software tool (typically Turbo C++) then the full path (absolute path)
of the file should be specified.
Data Structure of file is defined as FILE in library of Standard I/O function definitions. All files
should be declared as type FILE before they can be used. Only pointers can be declared of type
FILE.
Purpose (or mode) of the file is to specifies what kind operations that we can perform of the file.
General format:
FILE *fp;
fp=fopen(“filename”,”mode”);
Both filename and mode are specified strings and should be enclosed in double quotes.
When the mode is “w” (write), a file with given name is created it is not already existing.
The contents are deleted if already exists.
When mode is “a” (append), the previous contents are safe and the new data is appended
at the end of the file.
When the mode is “r” (read), the file is open with current contents safe, error occurs if the
file does not exist.
In addition to the above mode, there are 3 additional modes that many of the compilers today
support. They are:
r+ The existing file is opened to the beginning for both reading and writing.
w+ Same as “w” except for both reading and writing.
a+ Same as “a” except for both reading and writing.
Closing a File:
A file must be closed after all operations on it are completed. This ensures that all
outstanding info associated with the file is flushed out from buffer and all links are broken so to
allow other applications to use it if necessary. The function fclose() can be used to close a file.
getc() get the character from current position of the file and moves a position forward. It returns
the read character.
The constant EOF is used to indicate the end of the file. Therefore the character returned by
getc() is compared against EOF to check if end of file is reached.
The file pointer from which the character has to be read should sent as a argument to getc().
Eg: //assuming the file is already opened in read mode
while(c!=EOF)
c=getc(fp);
putc() is used to write a character to the current position of the file when the file is opened in
write mode. This function needs 2 arguments. First being the character that we want to place into
the file and second one is the pointer to the file in which we want to place the character.
Eg: putc(ch,fp);
{
int i,num;
FILE *f1,*f2,*f3;
clrscr();
f1=fopen("AllNumber","w+");
printf("Please enter %d numbers: ",MAX);
for(i=0;i<MAX;i++)
{
scanf("%d",&num);
putw(num,f1);
}
rewind(f1);
f2=fopen("OddNumbers","w");
f3=fopen("EvenNumbers","w");
while((num=getw(f1))!=EOF)
{
if(num%2==1)
putw(num,f2);
else
putw(num,f3);
}
fclose(f1);
fclose(f2);
fclose(f3);
printf("Numbers are written to files respectively");
getch();
}
Note: The files created by this program cannot be interpreted by normal text editor like notepad
of textpad. You can use the following code to read the number from files and check.
#include<stdio.h>
#define FILENAME “OddNumbers” //change the file name to match the name of your file before running the program
void main()
{
int n;
FILE *fp;
clrscr();
fp=fopen(FILENAME,"r");
while(1)
{
n=getw(fp);
if(n==EOF)
break;
To use command line arguments in your program, full declaration of the main function
should be used. When declared completely, main can actually accept two arguments: one
argument is number of command line arguments, and the other argument is a full list of all of the
command line arguments.
The full declaration is given in the following way:
void main(int argc, char *argv[])
{
…
}
When the program is invoked, the first argument is by default send as the name of the executable
(exe file) file to run the program. Therefore the count of arguments in argc will be count of
logical arguments plus one.
The list of arguments passed are stored in the argument vector argv and can be accessed as
argv[1], argv[2],…etc. Care should be taken we should not try to access non existing argument
(in the sense if only 2 arguments are passed to function we should not access the 3rd index of
argument vector). The value of argc can be verified to know the number of arguments received.
Eg: Program to copy the content of one file to another where the names of the files are sent as
command line arguments.
#include<stdio.h>
void main( int argc, char *agrv[])
{
FILE *fp1,*fp2; //declare to FILE pointers
char ch;
clrscr();
if(argc<3)
printf(“Enough parameters are not passed.”);
else
{
fp1=fopen(fname1,"r"); //open first file in read only mode
fp2=fopen(fname2,"w"); //open first file in write only mode
while(1) //infinite loop
{
ch=getc(fp1); //get the character at current position
if(ch==EOF) //if End Of File is reached then break the loop
break;
putc(ch,fp2); //else place the character into second file
}
fclose(fp1); //close both the files
fclose(fp2);
printf("\n\nThe content is copied into file %s is copied into file %ss", fname1,
fname2);
}
getch();
}
Note: The filenames should be sent as arguments to the file while running.
Space is used as delimiter between multiple arguments.