recursive fill function

Pages: 123
Sure

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
/*
* File: simpio.h
* Version: 1.0
* Last modified on Wed Apr 27 07:29:13 1994 by eroberts
* -----------------------------------------------------
* This interface provides access to a simple package of
* functions that simplify the reading of input data.
*/

#ifndef _simpio_h
#define _simpio_h

#include "genlib.h"

#define InitialBufferSize 120


/*
* Function: ReadLine
* Usage: s = ReadLine(infile);
* ----------------------------
* ReadLine reads a line of text from the input file and
* returns the line as a string.  The newline character
* that terminates the input is not stored as part of the
* string.  The ReadLine function returns NULL if infile
* is at the end-of-file position.
*/

//string ReadLine(FILE *infile);
string ReadLine(FILE *infile)
{
     string line, nline;
     int n, ch, size;

     n = 0;
     size = InitialBufferSize;
     line = (char *) GetBlock(size + 1);
     while ((ch = getc(infile)) != '\n' && ch != EOF)
     {
	  if (n == size)
          {
               size *= 2;
               nline = (string) GetBlock(size + 1);
               strncpy(nline,line,n);
               FreeBlock(line);
               line = nline;
          }
	  line[n++] = ch;
     }
     if (n == 0 && ch == EOF)
     {
          FreeBlock(line);
          return (NULL);
     }
     line[n] = '\0';
     nline = (string) GetBlock(n + 1);
     strcpy(nline , line);
     FreeBlock(line);
     return (nline);
}

/*
* Function: GetLine
* Usage: s = GetLine();
* ---------------------
* GetLine reads a line of text from standard input and returns
* the line as a string.  The newline character that terminates
* the input is not stored as part of the string.
*/

//string GetLine(void);
string GetLine(void)
{
     return (ReadLine(stdin));	
}


/*
* Function: GetInteger
* Usage: i = GetInteger();
* ------------------------
* GetInteger reads a line of text from standard input and scans
* it as an integer.  The integer value is returned.  If an
* integer cannot be scanned or if more characters follow the
* number, the user is given a chance to retry.
*/

//int GetInteger(void);
int GetInteger(void)
{
     string line;
     int value;
     char termch;

     while (1)
     {
	  line = GetLine();
	  switch (sscanf(line, " %d %c", &value, &termch))
          {
	       case 1:
                  FreeBlock(line);
                  return value;
           case 2:
                  printf("Unexpected character: '%c'\n", termch);
                  break;
           default:
                  printf("Please enter an integer\n");
                  break;
          }
          FreeBlock(line);
          printf("Retry: ");
     }
}

/*
* Function: GetLong
* Usage: l = GetLong();
* ---------------------
* GetLong reads a line of text from standard input and scans
* it as a long integer.  The value is returned as a long.
* If an integer cannot be scanned or if more characters follow
* the number, the user is given a chance to retry.
*/

//long GetLong(void);
long GetLong(void)
{
     string line;
     long value;
     char termch;

     while (1)
     {
	  line = (char *) GetLine();
	  switch (sscanf(line, " %ld %c", &value, &termch))
          {
	       case 1:
                  FreeBlock(line);
                  return value;
               case 2:
                  printf("Unexpected character: '%c'\n", termch);
                  break;
               default:
                  printf("Please enter an integer\n");
                  break;
          }
          FreeBlock(line);
          printf("Retry: ");
     }
}

/*
* Function: GetReal
* Usage: x = GetReal();
* ---------------------
* GetReal reads a line of text from standard input and scans
* it as a double.  If the number cannot be scanned or if extra
* characters follow after the number ends, the user is given
* a chance to reenter the value.
*/

//double GetReal(void);
double GetReal(void)
{
     string line;
     double value;
     char termch;

     while (1)
     {
	  line = GetLine();
	  switch (sscanf(line, " %lf %c", &value, &termch))
          {
	       case 1:
                  FreeBlock(line);
                  return value;
               case 2:
                  printf("Unexpected character: '%c'\n", termch);
                  break;
               default:
                  printf("Please enter an integer\n");
                  break;
          }
          FreeBlock(line);
          printf("Retry: ");
     }
}




#endif

=(
another header file....

genlib.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
/*
* File: genlib.h
* Version: 1.0
* Last modified on Sun Jul 24 10:32:49 1994 by eroberts
* -----------------------------------------------------
* This file contains several definitions that form the
* core of a general-purpose ANSI C library developed by Eric
* Roberts.  The goal of this library is to provide a basic
* set of tools and conventions that increase the readability
* of C programs, particularly as they are used in a teaching
* environment.
*
* The basic definitions provided by genlib.h are:
*
*    1.  Declarations for several new "primitive" types
*        (most importantly bool and string) that are
*        used throughout the other libraries and
*        applications as fundamental types.
*
*    2.  A new set of functions for memory allocation.
*
*    3.  A function for error handling.
*
*    4.  A repeat statement for loops with interior exits.
*/

#ifndef _genlib_h
#define _genlib_h

#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <stdarg.h>
#include <stdbool.h>

#define FALSE false
#define TRUE true
#define ErrorExitStatus 1


/* Section 1 -- Define new "primitive" types */

/*
* Type: bool
* ----------
* This type has two values, FALSE and TRUE, which are equal to 0
* and 1, respectively.  Most of the advantage of defining this type
* comes from readability because it allows the programmer to
* provide documentation that a variable will take on only one of
* these two values.  Designing a portable representation, however,
* is surprisingly hard, because many libraries and some compilers
* define these names.  The definitions are usually compatible but
* may still be flagged as errors.
*/



/*
* Type: string
* ------------
* The type string is identical to the type char *, which is
* traditionally used in C programs.  The main point of defining a
* new type is to improve program readability.   At the abstraction
* levels at which the type string is used, it is usually not
* important to take the string apart into its component characters.
* Declaring it as a string emphasizes this atomicity.
*/

typedef char *string;

/*
* Type: stream
* ------------
* Like string, the stream type is used to provide additional
* readability and is defined to be equivalent to FILE *
* (which is particularly confusing because it violates
* standard case conventions).  This type is not used in
* the text but is preserved in genlib.h, so it is possible
* to teach all of CS1 without exposing any pointers.
*/

typedef FILE *stream;

/*
* Constant: UNDEFINED
* -------------------
* Besides NULL, the only other constant of pointer type is
* UNDEFINED, which is used in certain packages as a special
* sentinel to indicate an undefined pointer value.  In many
* such contexts, NULL is a legitimate data value and is
* therefore inappropriate as a sentinel.
*/

#define UNDEFINED ((void *) undefined_object)

extern char undefined_object[];
char undefined_object[] = "UNDEFINED";

/* Section 2 -- Memory allocation */

/*
* General notes:
* --------------
* These functions provide a common interface for memory
* allocation.  All functions in the library that allocate
* memory do so using GetBlock and FreeBlock.  Even though
* the ANSI standard defines malloc and free for the same
* purpose, using GetBlock and FreeBlock provides greater
* compatibility with non-ANSI implementations, automatic
* out-of-memory error detection, and the possibility of
* substituting a garbage-collecting allocator.
*/

/*
* Function: GetBlock
* Usage: ptr = (type) GetBlock(nbytes);
* -------------------------------------
* GetBlock allocates a block of memory of the given size.  If
* no memory is available, GetBlock generates an error.
*/

void *GetBlock(size_t nbytes);

void *GetBlock(size_t nbytes)
{
     void *result;
     result = malloc(nbytes);
     //if (result == NULL) Error("No memory available");
     return result;
}

/*
* Function: FreeBlock
* Usage: FreeBlock(ptr);
* ----------------------
* FreeBlock frees the memory associated with ptr, which must
* have been allocated using GetBlock, New, or NewArray.
*/

void FreeBlock(void *ptr);

void FreeBlock(void *ptr)
{
     free(ptr);
}

/*
* Macro: New
* Usage: p = New(pointer-type);
* -----------------------------
* The New pseudofunction allocates enough space to hold an
* object of the type to which pointer-type points and returns
* a pointer to the newly allocated pointer.  Note that
* "New" is different from the "new" operator used in C++;
* the former takes a pointer type and the latter takes the
* target type.
*/

#define New(type) ((type) GetBlock(sizeof *((type) NULL)))

/*
* Macro: NewArray
* Usage: p = NewArray(n, element-type);
* -------------------------------------
* NewArray allocates enough space to hold an array of n
* values of the specified element type.
*/

#define NewArray(n, type) ((type *) GetBlock((n) * sizeof (type)))

/* Section 3 -- Basic error handling */

/*
* Function: Error
* Usage: Error(msg, ...)
* ----------------------
* Error generates an error string, expanding % constructions
* appearing in the error message string just as printf does.
* If an error handler exception has been introduced (see the
* "exception.h" facility), the ErrorException exception is
* raised with the expanded error string as argument.  If
* there is no ErrorException defined, the program exits
* with a status code indicating failure (as given by the
* constant ErrorExitStatus).  The length of the error
* message string following expansion must not exceed
* MaxErrorMessage, and it is the client's responsibility
* to ensure this.
*/


void Error(string msg, ...);
void Error(string msg, ...)
{
     va_list args;

     va_start(args,msg);
     fprintf(stderr, "Error: ");
     vfprintf(stderr, msg, args);
     fprintf(stderr, "\n");
     va_end(args);
     exit(ErrorExitStatus);
}


/* Section 4 -- The repeat pseudo-statement */

/*
* Statement form: repeat { ... }
* ------------------------------
* Some instructors who have taught CS1 using this library
* have found that using
*
*     while (TRUE)
*
* to initiate a loop with an interior exit is confusing to
* students, particularly when it comes at the beginning of
* the course.  This macro defines "repeat" as an infinite
* loop construct for instructors who find it easier to
* explain, although it is not used in the text.   Similar
* macro definitions are common in industry.
*/

#define repeat for (;;)

/* Section 5 -- Special code for the Borland C compiler */

/*
* Three changes need to be incorporated into the definition of
* genlib.h for optimal compatibility with the Borland C compiler.
* First, if main does not return a value, the compiler generates
* a warning, even though returning a value is not required by
* most other compilers.  Second, in the standard confiuration, DOS
* programs exit immediately upon completion.  If the program
* is being run directly from the compiler -- as is almost
* certain the case during the testing phase -- the output
* disappears before the student to read the screen.  Third,
* there is no check to see that applications are compiled
* with the proper memory-model options; if the wrong setting
* is used, the program compiles and loads correctly, but then
* crashes on the first library call.
*
* To fix these problems, genlib.h has been extended to test
* for the Borland compiler and then redefines main in that case.
* Moreover, unless the program is being assembled for Windows,
* the new definition of main also waits for the user to hit the
* return or enter key before exiting.  To disable this feature
* in a DOS application program that uses genlib.h, include an
* explicit exit(0) call in the definition of main.
*/

#if defined( __BORLANDC__ )

#  if !defined ( __LARGE__ )
#    error The genlib.h library requires the LARGE memory model.
#  endif

#  if defined( _Windows )
#    define main void main
#  else
#    define main() void Main(void); \
            main() \
            { \
                Main(); \
                (void) getchar(); \
                return (0); \
            } \
            void Main(void)
#  endif /* _Windows */

#endif /* __BORLANDC__ */

#endif
now I see what's your problem is

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

void fillArray(char shape[MAX_ROW][MAX_COL], int row, int column)
{
     int r, c;
     printf("Enter the interior point(where the program will start filling)\n");
     printf("Enter the row number\n");
     r=GetInteger();
     printf("Enter the column number\n");
     c=GetInteger();
	 /*
     if (r < 0 || r > row || c > column || c < 0) return;
     if (shape[r][c] == '*' || shape[r][c] == '#') return;
     shape[r][c] = '*';
	*/
	 cout<<"here";
	 fillArray(shape,r+1,c);//down <----- this function call is an infinite loop
                                           //why? think of it
	 fillArray(shape,r-1,c);//up <<--- can't even do this.
	 fillArray(shape,r,c-1);//left
	 fillArray(shape,r,c+1);//right
}


Sorry for the late reply, my connection to internet was disconnected
So I should re-think my fillArray function prototype?
Now my program crashes

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <stdio.h>
#include "simpio.h"

const int MAX_ROW = 200;
const int MAX_COL = 200;

void getshape(char shape[MAX_ROW][MAX_COL]);
void fillArray(char shape[MAX_ROW][MAX_COL], int row, int column);
int main()
{
    int r, c;
    char shape[MAX_ROW][MAX_COL];
    int row=0, column=0;
    printf("Enter the interior point where the program where start filling\n");                                                
    row=GetInteger();
    column=GetInteger();
    getshape(shape);
    shape[MAX_ROW][MAX_COL] = '*';
    fillArray(shape, row, column);
    getchar();
    return 0;
}
void getshape(char shape[MAX_ROW][MAX_COL])
{
     char end='.';
     printf("Enter a shape and when your done enter '.'\n");
     while ((end=getchar()) != '.')
     {
           shape[MAX_ROW][MAX_COL]=getchar();
     }
     return;
}
void fillArray(char shape[MAX_ROW][MAX_COL], int row, int column)
{
    if (shape[row][column] == '*' || shape[row][column] == '#') return;
    else
    {
     shape[row][column] = '*';
	
	 fillArray(shape,row+1,column);//down
	 fillArray(shape,row-2,column);//up
	 fillArray(shape,row,column-1);//left
	 fillArray(shape,row,column+2);//right
  }
}
1
2
3
4
	 fillArray(shape,row+1,column);//down
	 fillArray(shape,row-2,column);//up
	 fillArray(shape,row,column-1);//left
	 fillArray(shape,row,column+2);//right 


I suggest you to use 2d array on this.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void fillRowColumn(char fshape, int frow, fcol){
  

    int anyName[4][2] = 
       {{frow+1,fcol},
         {frow-2, fcol},
         {frow, fcol-1},
         {frow, fcol+2}};
    //then make count from 4, to fill all. if count = 4, then go to getShape() function
    //my brain isn't working today.
    fillArray(fshape, anyName[fillCount][0], anyName[fillCount][1]);
 
}
void fillArray(...)
{
    ...
    fillRowColumn(shape,row,column);
}
Last edited on
I'm not sure I'm understanding you. And sorry about the late response my internet went down.
Ok let me clarify your code...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void fillArray(char shape[MAX_ROW][MAX_COL], int row, int column)
{
    if (shape[row][column] == '*' || shape[row][column] == '#') return;
    else
    {
     shape[row][column] = '*';
	
	 fillArray(shape,row+1,column);//down<-- this function call repeats again and again..
	 fillArray(shape,row-2,column);//up <---this will not be implemented?? why? see your code
                                                      //if you call fillArray() function.. it will first do the first function
                                                     //call which is 
fillArray(shape,row+1,column);
//now it will do the step again for fillArray() function... now what?? I will call again the //
fillArray(shape,row+1,column);
you understand now? it won't do the
//second call which is fillArray(shape,row-2,column); /* simply, it will recurse at fillArray(shape,row+1,column); only? did you get it now? */
How Can i get input of array by recursive function
How Can i get input of 1d array by recursive function
I don't understand your question at all.

do you mean that for every recursion of the function you want to get the value? of the array?
How would i make it so the program continues the function prototypes instead of repeating the one? I know a break wouldn't work since there is no loop or switch statement. And a return wouldn't work since that would end the function.
Make two functions that call each other, so that the four states (up,down,left, and right) will be implemented..

or

pass all the values to the recursive function

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void fillRowColumn(char fshape, int frow, fcol){
  

    int anyName[4][2] = 
       {{frow+1,fcol},
         {frow-2, fcol},
         {frow, fcol-1},
         {frow, fcol+2}};
    fillArray(anyName[0][0], anyName[0][1], ..., anyName[3][0], anyName[3][1]);
         //you can also make a loop for this one...
         //for now that's the only solution I come up. but there is still much better algo for this
         //just think about it. Hope this helps
 
}
Sorry about the late response I have been busy. Anyways, I was wondering is there is a way to determine the size of a 2D array?.
What do you mean by size?
The max index of a 2D array? like arsize[4][2]? which is 4 by 2?? or sizeof(arsize)??
If the max size of the index your determining, I guess just make a nested for loop.
Compare if the array index is equal to NULL or '\0'.
Sorry I didn't word that very good. What I mean is how can I determine the number of rows and columns.
if your declaration of a 2D array is like this

ar[4][2];

you can easily get the row and column.

you can define first

const MAX_ROW = 4;
const MAX_COL = 2;

then

int? ar[MAX_ROW][MAX_COL];

now the number of rows is 4 and number of columns is 2;

But if you have a definition like this

ar[1000][1000];

and you only initialize or put a value at certain number of rows and columns.

like for example ar[0][0] to ar[200][203] only have a value.

you can use for loop in determining number of rows or columns.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int i, j;
int collen = 1000, rowlen = 1000;

    for(i=0;i<rowlen;i++){
        for(j = 0; j <collen; j++){
            if(ar[i][j] == '\0' && ar[i-1][j] == '\0'){
               collen = j;
               break;
               }
            if(ar[i][j] == '\0' && ar[i][j-1] == '\0'){
              rowlen = i;
              break;
            }
       }
       if(row != 1000 && col != 1000)
           break;
   }

Last edited on
Okay thanks.
How would I make two functions that call each other, so that the four states (up,down,left, and right) will be implemented if the program is recursive?
Pages: 123