364 Intermediate C Programming
}18
fptr = fopen ( argv [1] , " r") ;19
i f ( fptr == NULL )20
{21
printf (" fopen fail . n") ;22
return EXIT _FAILUR E ;23
}24
numbe rColumn = 0;25
// get the numbers of rows and columns26
do27
{28
ch = fgetc ( fptr );29
i f ( ch != EOF )30
{31
i f ( ch == n)32
{33
row ++;34
numbe rColumn = column ;35
column = 0;36
}37
e l s e38
{39
column ++;40
}41
}42
} while ( ch != EOF );43
numberRow = row ;44
// allocat e memory for the mazeArr45
mazeArr = malloc ( numbe r Row * s i z e o f ( in t *) );46
for ( row = 0; row < numberRow ; row ++)47
{48
mazeArr [ row ] = malloc ( nu mberColu mn * s i z e o f ( in t ) );49
}50
// return to the begi n ning of the file51
fseek ( fptr , 0, SEEK_SET );52
// read the file again and fill the two - dim ensional array53
row = 0;54
column = 0;55
do56
{57
ch = fgetc ( fptr );58
i f ( ch != EOF )59
{60
i f ( ch == n)61
{62
row ++;63
column = 0;64
}65
e l s e66
{67
mazeArr [ row ][ column ] = ch ;68
Finding the Exit of a Maze 365
column ++;69
}70
}71
} while ( ch != EOF );72
fclose ( fptr );73
printf (" The mazeArr has % d rows and % d columns . n " ,74
numberRow , numbe rColumn ) ;75
for ( row = 0; row < numberRow ; row ++)76
{77
for ( column = 0; column < numb erColum n ; column ++)78
{79
printf (" %c" , mazeArr [ row ][ column ]);80
}81
printf (" n" );82
}83
// release the memory84
for ( row = 0; row < numberRow ; row ++)85
{86
free ( mazeArr [ row ]);87
}88
free ( mazeArr ) ;89
return EXIT _SUCCES S ;90
}91
The program stores the maze in a two-dimensional array called mazeArr. With mazeArr,
it is easier to determine whether a particular cell is a brick by giving the row and column
indexes. There is a fundamental problem, however: Several pieces of information are not
stored anywhere with the array. For example, the size of the maze, the location of the exit,
and the location of the starting point. It is better to create a structure so that all of this
related information can be better organized.
22.3 The Maze Structure
A structure is defined to store relevant information about a maze. This structure stores
the maze’s size (number of rows and number of columns), the starting location, the exit lo-
cation, and the current location during movement. The structure also has a two-dimensional
array to store the information for each cell in the maze. A constructor function creates and
initializes the maze object by reading a file. The destructor function releases the memory
used in the maze object, and is called before the program ends.
Below is the code listing for the header file. It includes the definition for Maze structure,
as well as the constructor and destructor functions.
/* maze . h */1
#i f n d e f MAZE_H2
#d ef in e MAZE_H3
#d ef in e STAR T SYMBOL s 4
#d ef in e EXITSY MBOL E 5
#d ef in e BRIC K SYMBOL * 6
#d ef in e COR RIDORS YMBOL 7
366 Intermediate C Programming
#d ef in e INV A LIDSYM BOL -8
typedef s t ru ct9
{10
int numRow , numCol ; // size of the maze11
int startRow , startCol ; // sta r ting locatio n12
int exitRow , exitCol ; // exit location13
int curRow , curCol ; // current location14
// brick ? exit ? starting point ? corridor ? 2 - dim ensional15
// array storing the cells16
int * * cells ;17
} Maze ;18
// directions , ORIGIN marks the starting point19
enum { ORIGIN , EAST , SOUTH , WEST , NORTH };20
// move forward , backward , or found exit alread21
enum { FORWARD , BACKWARD , DONE };22
// read the maze from a file23
Maze * Maze _const r uct ( char * fi l eName );24
// release memory before the program ends25
void Maze_ destruc t ( Maze * mz ) ;26
// print the maze s prope rties ( mainly for debu g ging )27
void Maze_pri n t ( Maze * mz ) ;28
#e ndif29
The following listing gives sample implementations for the functions declared in the
header file.
// mazerea d . c1
#in clude " maze .h "2
#in clude < stdio .h >3
#in clude < stdlib .h >4
// A static fu n c tion can be called by another funct i o n5
// in the same file . A static function cannot be called6
// by any function outside this file .7
// If ptr is NULL , print an error message and exit8
s t a t i c void checkMal l oc ( void * ptr , char * mes s a g e );9
// find the length of a line in a file ( EOF or n )10
s t a t i c i n t fin dLineL ength ( FILE * fh ) ;11
// Find the numbers of rows and columns . If the maze is not12
// rectangular , use the widest row13
s t a t i c void Maze_f i ndSize ( FILE * fh , in t * numRow ,14
int * numCol );15
s t a t i c void checkMal l oc ( void * ptr , char * mes s a g e )16
{17
i f ( ptr == NULL ) // malloc fail18
{19
printf (" malloc for %s fail n " , message ) ;20
}21
}22
s t a t i c i n t fin dLineL ength ( FILE * fh )23
{24
int ch ;25
int length = 0;26
Finding the Exit of a Maze 367
i f ( feof ( fh )) { return -1; }27
do28
{29
ch = fgetc ( fh ); // read one character30
length ++;31
} while (( ch != n ) && ( ch != EOF ) );32
return length ;33
}34
s t a t i c void Maze_f i ndSize ( FILE * fh , in t * numRow , in t *35
numCol )36
{37
int row = 0;38
int col = 0;39
int maxCol = 0;40
// find the maximum number of columns . This allows the41
// program to handle a maze that is not r ectangula r .42
do43
{44
col = f indLin eLengt h ( fh );45
i f ( col != -1)46
{47
i f ( maxCol < col ) { maxCol = col ; }48
row ++;49
}50
} while ( col != -1);51
* numRow = row ;52
* numCol = maxCol ;53
}54
Maze * Maze _const r uct ( char * fi l eName )55
{56
int numRow = 0;57
int numCol = 0;58
int row , col ;59
int ch ;60
FILE * fptr = fopen ( fileName , "r ");61
i f ( fptr == 0)62
{63
fprintf ( stderr , " open %s fail n" , fi l e Name );64
return NULL ;65
}66
Maze_ findSiz e ( fptr , & numRow , & numCol );67
Maze * mzptr = malloc ( s i z e o f ( Maze ) );68
checkM alloc ( mzptr , " mzptr " ) ;69
mzptr -> numRow = numRow ;70
mzptr -> numCol = numCol ;71
// create a two - dime n sional array to store the cells72
mzptr -> cells = malloc ( numRow * s i z e o f ( i nt *) );73
checkM alloc ( mzptr -> cells , " mzptr -> cells " );74
for ( row = 0; row < numRow ; row ++)75
{76
mzptr -> cells [ row ] = malloc ( numCol * s i z e o f ( in t ) );77
368 Intermediate C Programming
checkM alloc ( mzptr -> cells [ row ],78
" mzptr -> cells [ row ] ");79
// ini tialize the cells to invalid80
for ( col = 0; col < numCol ; col ++)81
{82
( mzptr -> cells )[ row ][ col ] = INVA L IDSYMB OL ;83
}84
}85
// move fptr to the beginning86
fseek ( fptr , 0, SEEK_SET );87
// read the file again and fill the two - dim ensional array88
row = 0;89
while ((! feof ( fptr )) && ( ch != EOF ) && ( row < numRow ) )90
{91
// fill one row92
col = 0;93
do94
{95
ch = fgetc ( fptr );96
i f ( ch != EOF )97
{98
// notice that n is also stored99
( mzptr -> cells )[ row ][ col ] = ch ;100
switch ( ch )101
{102
case STARTSYM BOL :103
mzptr -> start R o w = row ;104
mzptr -> start C o l = col ;105
mzptr -> curRow = row ;106
mzptr -> curCol = col ;107
break;108
case EXITSYMBOL :109
mzptr -> exitRow = row ;110
mzptr -> exitCol = col ;111
break;112
}113
col ++;114
}115
} while (( ch != EOF ) && ( ch != n )) ;116
// checkin g n" to handle non - recta ngular mazes117
row ++;118
}119
fclose ( fptr );120
return mzptr ;121
}122
// release the memory123
void Maze_ destruc t ( Maze * mzptr )124
{125
int row ;126
for ( row = 0; row < ( mzptr -> numRow ); row ++)127
{ free (( mzptr -> cells ) [ row ]) ; }128
..................Content has been hidden....................

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