You use isspace to detect whitespace. isspace will return true for
several other characters besides these three.
I mean whatever whitespace there is, newlines, tabs etc etc. I will change
the comments to reflect this.
Surely this has been mentioned before. ppc contains the address of
pword in main. It can never be NULL. You probably meant *ppc.
Oh.. my .. I reall don't understand why the program was working with this
bug.
And I know your excessive vertical white space has been discussed.
Vertical white space is a matter of style but, to be blunt, yours sucks.
:-\
between function definitions: 2 vertical tabs
between variable assignments and variable 1 vertical tab
initializations:
point where variable assignments and/or 2 vertical tabs
initializations end and other expressions
start:
just before final return statement: 2 vertical tabs
Thats my style. is there something wrong with it ?
While neither condition applies in this case, for practice you could
attempt to compartmentalize some aspect of g_s_w. As an example, you
could move the 16 lines of code that deal with reallocating the space
*ppc points to into a separate function. It would require only three
arguments (the current value of *ppc, the address of word length, and
the address of new_mem).
I tried it but i get dangling pointer errors. See below for code.
They are mutually exclusive in this case so you only need to use one or
the other. If the one you use returns 1, then that condition is true.
(E.g., if you use feof and it returns 1, then you reached end of file
and don't have an error). If the one you use returns 0, then the other
condition is true.
/* 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 is defined
* by isspace().
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
enum { WORD_SIZE = 2 };
enum { GSW_OK, GSW_ENOMEM, GSW_ENORESIZE } ;
int get_single_word( char** );
int alloc_new_mem( char** , char**, char**, size_t* );
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 = EOF;
size_t word_length = WORD_SIZE;
char* word_begin = NULL;
char* new_mem = NULL;
size_t* pwl = &word_length;
*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++ )
{
if( GSW_OK != alloc_new_mem( ppc, &word_begin, &new_mem, pwl ) )
{
return GSW_ENORESIZE;
}
}
*word_begin++ = ch;
}
*word_begin = '\0';
return GSW_OK;
}
int alloc_new_mem( char** ppc, char** word_begin, char** new_mem, size_t* pwl )
{
size_t word_length_interval = 2;
*new_mem = realloc( *ppc, (word_length_interval * WORD_SIZE * sizeof **new_mem) );
if( *new_mem )
{
*word_begin = *new_mem + (*word_begin - *ppc);
*pwl *= word_length_interval;
*ppc = *new_mem;
}
else
{
**word_begin = '\0';
return GSW_ENORESIZE;
}
return GSW_OK;
}
========================= OUTPUT =====================
[arnuld@dune ztest]$ gcc -ansi -pedantic -Wall -Wextra get-single-word.c
[arnuld@dune ztest]$ ./a.out
Love
You entered: [Love]
Looooooooooooooooooooooooooooooooooooooooooooooooooove
*** glibc detected *** realloc(): invalid next size: 0x09068008 ***
Aborted
[arnuld@dune ztest]