A
arnuld
We have discussed this program a lot. Only two problems have remained with
this code:
/* a function written in ANSI C, that takes a word from stdin and manages the memory dynamically
*
* Since there is no generally agreed definition of what a 'word' is. I have taken a very simple
* approach:
*
* A word is a contiguous collection of non-whitespace characters. A whitespace means anyone of
* a single apace, a newline or a tab.
*
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
enum { WORD_SIZE = 28 };
enum { GSW_OK, GSW_ENOMEM, GSW_ENORESIZE } ;
int get_single_word( char** );
int main( void )
{
char* pword;
while( (GSW_OK == get_single_word(&pword)) && ( *pword != 0) )
{
printf("You entered: [%s]\n", pword);
free( pword );
}
return 0;
}
int get_single_word( char** ppc )
{
unsigned ele_num = 0;
int ch;
size_t word_length = WORD_SIZE;
size_t word_length_interval = 2;
char* word_begin;
char* new_mem;
*ppc = malloc(word_length * sizeof(**ppc));
word_begin = *ppc;
if( NULL == ppc )
{
return GSW_ENOMEM;
}
while( (EOF != (ch = getchar())) && isspace(ch) )
{
continue; /* Leading whitespace */
}
if( EOF != ch )
{
*word_begin++ = ch;
ele_num = 1;
}
while( (EOF != (ch = getchar())) && (! isspace(ch)) )
{
if( (word_length - 1) == ele_num++ )
{
new_mem = realloc( *ppc, (word_length_interval * word_length * sizeof *new_mem) );
if( new_mem )
{
word_begin = new_mem + (word_begin - *ppc);
word_length *= word_length_interval;
*ppc = new_mem;
}
else
{
*word_begin = '\0';
return GSW_ENORESIZE;
}
}
*word_begin++ = ch;
}
*word_begin = '\0';
return GSW_OK;
}
1) the get_single_word program is 60 lines long when there is
general agreement that no function should be longer than 40
lines.
2) distinguishing between real EOF and the error.
For (1) all I can think of is to take while() loop (from
get_single_word) out into a new function which will require passing 6
variables as pointer (or pointer to pointer) arguments: new_mem,
word_begin, word_length, word_length_interval, ppc and ele_num. I think
that will be messy solution.
Regarding (2) I have to use feof() and ferror() which are little
confusing.
this code:
/* a function written in ANSI C, that takes a word from stdin and manages the memory dynamically
*
* Since there is no generally agreed definition of what a 'word' is. I have taken a very simple
* approach:
*
* A word is a contiguous collection of non-whitespace characters. A whitespace means anyone of
* a single apace, a newline or a tab.
*
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
enum { WORD_SIZE = 28 };
enum { GSW_OK, GSW_ENOMEM, GSW_ENORESIZE } ;
int get_single_word( char** );
int main( void )
{
char* pword;
while( (GSW_OK == get_single_word(&pword)) && ( *pword != 0) )
{
printf("You entered: [%s]\n", pword);
free( pword );
}
return 0;
}
int get_single_word( char** ppc )
{
unsigned ele_num = 0;
int ch;
size_t word_length = WORD_SIZE;
size_t word_length_interval = 2;
char* word_begin;
char* new_mem;
*ppc = malloc(word_length * sizeof(**ppc));
word_begin = *ppc;
if( NULL == ppc )
{
return GSW_ENOMEM;
}
while( (EOF != (ch = getchar())) && isspace(ch) )
{
continue; /* Leading whitespace */
}
if( EOF != ch )
{
*word_begin++ = ch;
ele_num = 1;
}
while( (EOF != (ch = getchar())) && (! isspace(ch)) )
{
if( (word_length - 1) == ele_num++ )
{
new_mem = realloc( *ppc, (word_length_interval * word_length * sizeof *new_mem) );
if( new_mem )
{
word_begin = new_mem + (word_begin - *ppc);
word_length *= word_length_interval;
*ppc = new_mem;
}
else
{
*word_begin = '\0';
return GSW_ENORESIZE;
}
}
*word_begin++ = ch;
}
*word_begin = '\0';
return GSW_OK;
}
1) the get_single_word program is 60 lines long when there is
general agreement that no function should be longer than 40
lines.
2) distinguishing between real EOF and the error.
For (1) all I can think of is to take while() loop (from
get_single_word) out into a new function which will require passing 6
variables as pointer (or pointer to pointer) arguments: new_mem,
word_begin, word_length, word_length_interval, ppc and ele_num. I think
that will be messy solution.
Regarding (2) I have to use feof() and ferror() which are little
confusing.