Chapter 17
Programming Problems Using Structure
17.1 Sorting a Person Database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275
17.2 Packing Decimal Digits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281
17.2.1 Number Systems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281
17.2.2 Packing Two Decimal Digits into One Byte . . . . . . . . . . . . . . . . . . . . . . . . . . 282
17.2.3 Bit Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 283
17.2.4 Inserting and Retrieving Decimal Digits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 285
17.2.5 DecPack Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 286
17.3 Binary File and Pointer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 290
17.1 Sorting a Person Database
In this problem we sort a database of people. Each person is an object that has two
attributes: name and age. The program sorts the people by ages or by names. To test the
program, we use the 200 popular given names. The names are randomly ordered by using
the Linux command sort with -R. The age of a person is a random number between 1 and
100. The database is a text file containing two columns: age and name. A few lines of the
database are shown below:
43 Peter
87 Linda
57 Gregory
61 Larry
5 Eric
19 Dennis
56 Betty
70 Joshua
4 Donald
60 Susan
To test the program, we need to compare the answers of our program against the correct
answers. We can use the Linux program sort to generate the correct answers. The correct
answers are generated as follows:
sort -n: sort the first column and treat the column as numbers. Without -n, the first
column will be treated as strings and “10” is before “9” because 1 is before 9 in the
dictionary.
sort -k 2: sort by the second column.
This program uses the same Person structure defined earlier. Another structure is de-
fined to store an array of pointers to Person objects. This structure also has an attribute
as the number of pointers in the array. The program needs to implement the follow steps:
1. Read Person objects from a file.
275
276 Intermediate C Programming
2. Write Person objects to a file.
3. Sort Person objects by names.
4. Sort Person objects by ages.
5. Release memory occupied by the objects.
6. Close opened files.
Below is the header file:
// person . h1
#i f n d e f PERSON_H2
#d ef in e PERSON_H3
typedef s t ru ct4
{5
int age ;6
char * name ;7
} Person ;8
typedef s t ru ct9
{10
int number ; // number of persons11
Person * * person ; // array of pointers to Person ob j ects12
} Pe rsonDa tabase ;13
// read person database from a file14
// person is an array of pointers to person ob j ects15
// The functi o n returns the pointer of a d a tabase or NULL16
// The functi o n returns NULL if reading from the file fails17
Pers o nDatab ase * Perso n_read ( char * filenam e ) ;18
void Pers on_so rtByN a me ( Pe rsonDa tabase * perdb );19
void Pers on_sor tByAg e ( Pers onData base * perdb );20
// save the database in a file21
// return 0 if fail22
// return 1 if succeed23
int Person _write ( char * filename , P ersonD atabas e * perdb );24
// write to co m p uter screen25
void Person _print ( Perso nDatab ase * perdb ) ;26
// release the memory of the database27
void Pers o n_des truct ( Pers o nData b ase * perdb ) ;28
#e ndif29
Here are implementations of these functions:
// person . c1
#in clude " person .h "2
#in clude < stdio .h >3
#in clude < string .h >4
#in clude < stdlib .h >5
Pers o nDatab ase * Perso n_read ( char * filenam e )6
{7
FILE * fptr = fopen ( filename , "r ");8
i f ( fptr == NULL )9
{10
return NULL ;11
}12
Pers o nDatab ase * perdb = malloc ( s i z e o f ( Per s onData base )) ;13
i f ( perdb == NULL )14
Programming Problems Using Structure 277
{15
fclose ( fptr );16
return NULL ;17
}18
// count the number of people in the file19
// use the longest name for the size of the buffer20
int numPerson = 0;21
int longest Name = 0; // length of buffer to read names22
while (! feof ( fptr ) )23
{24
int age ;25
// find a line that contains a number ( age )26
i f ( fscanf ( fptr , " %d " , & age ) == 1)27
{28
numPerson ++;29
// the remani n g char acters are the name30
int nameLeng t h = 0;31
while ((! feof ( fptr ) ) && ( fgetc ( fptr ) != n ))32
{33
nameLen g th ++;34
}35
nameLen g th ++; // for n 36
i f ( lo ngestName < n a meLength )37
{38
longes tName = nameLe n gth ;39
}40
}41
}42
// the number of person is known now43
perdb -> number = n umPerson ;44
perdb -> person = malloc ( s i z e o f ( Person *) * n u mPerson ) ;45
// allocat e a buffer to read the names46
char * name = malloc ( s i z e o f ( char) * longest Name ) ;47
int ind = 0;48
// read the file again and store the data in the database49
// return to the begi n ning of the file50
fseek ( fptr , 0 , SEEK_SET );51
while (! feof ( fptr ) )52
{53
int age ;54
i f ( fscanf ( fptr , " %d " , & age ) == 1)55
{56
// remove the space sep arating age and name57
fgetc ( fptr );58
fgets ( name , longestName , fptr );59
// remove n60
char * chptr = strchr ( name , n) ;61
i f ( chptr != NULL ) // last line may not have n 62
{63
* chptr = 0 ;64
}65
278 Intermediate C Programming
perdb -> person [ ind ] = malloc ( s i z e o f ( Person )) ;66
perdb -> person [ ind ] -> age = age ;67
// strdup calls malloc68
perdb -> person [ ind ] -> name = strdup ( name );69
ind ++;70
}71
}72
free ( name );73
fclose ( fptr );74
return perdb ;75
}76
s t a t i c void Perso n_writ eHelp ( FILE * fptr ,77
Pers o nDatab ase * perdb )78
{79
int ind ;80
for ( ind = 0; ind < perdb -> number ; ind ++)81
{82
// write one person per line83
fprintf ( fptr , " %d %s n" ,84
perdb -> person [ ind ] -> age ,85
perdb -> person [ ind ] -> name );86
}87
}88
void Person _print ( Perso nDatab ase * perdb )89
{90
printf (" - --- --- --- --- --- -- - -- --- --- --- --- --- --- n") ;91
// stdout is a built - in FILE *92
// stdout means the output is sent to the comp u ter screen93
// not a file on the disk94
Pers on_wr i teHel p ( stdout , perdb );95
}96
int Person _write ( char * filename , P ersonD atabas e * perdb )97
{98
i f ( perdb == NULL )99
{100
// nothing in the d atabase101
return 0;102
}103
FILE * fptr = fopen ( filename , "w ");104
i f ( fptr == NULL )105
{106
// cannot open the file107
return 0;108
}109
Pers on_wr i teHel p ( fptr , perdb );110
fclose ( fptr );111
return 1;112
}113
s t a t i c i n t com parebyN ame ( const void * p1 ,114
const void * p2)115
{116
Programming Problems Using Structure 279
// get add r esses of the array elements117
const Person * * pp1 = ( const Person * *) p1 ;118
const Person * * pp2 = ( const Person * *) p2 ;119
// get the elem e nts120
const Person const * pv1 = * pp1 ;121
const Person const * pv2 = * pp2 ;122
// compare the attribu tes123
return strcmp (( pv1 -> name ) , ( pv2 -> name )) ;124
}125
void Pers on_so rtByN a me ( Pe rsonDa tabase * perdb )126
{127
qsort ( perdb -> person , perdb -> number ,128
s i z e o f ( Person *) , comp a rebyNa me ) ;129
}130
s t a t i c i n t com p arebyAg e ( const void * p1 ,131
const void * p2)132
{133
const Person * * pp1 = ( const Person * *) p1 ;134
const Person * * pp2 = ( const Person * *) p2 ;135
const Person * pv1 = * pp1 ;136
const Person * pv2 = * pp2 ;137
return (( pv1 -> age ) - ( pv2 -> age )) ;138
}139
void Pers on_sor tByAg e ( Pers onData base * perdb )140
{141
qsort ( perdb -> person , perdb -> number ,142
s i z e o f ( Person *) , compa rebyAge ) ;143
}144
void Pers o n_des truct ( Pers onData b ase * perdb )145
{146
int ind ;147
for ( ind = 0; ind < perdb -> number ; ind ++)148
{149
free ( perdb -> person [ ind ] -> name );150
free ( perdb -> person [ ind ]);151
}152
free ( perdb -> person );153
free ( perdb ) ;154
}155
This is the main function:
// main . c1
#in clude < stdio .h >2
#in clude < stdlib .h >3
#in clude < string .h >4
#in clude " person .h "5
int main ( i n t argc , char * argv [])6
{7
// argv [1]: name of input file8
// argv [2]: name of output file ( sort by name )9
// argv [3]: name of output file ( sort by age )10
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset