Any way to take a word as input from stdin ?

D

David Thompson

No, it will not.

<OT> The input stream tokenises the input. The C++ standard defines how
formatted input is tokenised. </OT>

<OT> He's closer than you are. The istream doesn't tokenize; the
extractor (aka >>) for std::string does. The standard does define
this, although as dependent on locale functionality which is
implementation-dependent -- but a locale that significantly changes
whitespace would be perverse.

- formerly david.thompson1 || achar(64) || worldnet.att.net
 
D

David Thompson

It's not clear (to me) if 'this feature' is input of unbounded-length
lines or of parsing words (defined as non-white); but either way ...
Because C was designed for /implementing/ this feature; as a bare-bones
systems programming language.
Actually it was designed primarily to implement an OS, which by its
nature has a pretty significant overlap with language support and
similar low-level utilities, although in practice it has been used for
a much wider range of tools and applications.
I'd be interested in real evidence for this claim. Real, as in, it
happened in these programs and couldn't be eliminated by straightforward
fixes, rather than contrived examples or beginners gotchas.
Terminated strings in general are faster for some things and in some
cases and slower for others than counted. Especially in strict
sequential execution (little or no overlap, little or no caching, no
speculation) which was the common case then. If you use terminated, a
terminator of null is usually fastest, because many machines can
'compare' to zero more efficiently than any other value.

But since C was not originally envisioned/expected to be used for very
extensive text or string processing, I think the decision was more
(mostly) what was easy and fast to _implement_.
That seems ... unlikely ... to me. Just because one's assembler has
an ASCIZ directive doesn't mean one has to use it; even if one does,
one can perfectly well also associate a length with a string as well
as a null terminator.
Agree (both). Morever C wasn't developed on the -7; B was, but the
evolution into C (which occurred in several stages) began on the -11.
I'm pretty sure no DEC before VAX had standard hardware support for
either kind of string, although some -11 models did have an optional
'commercial instruction set' tailored for COBOL (or DIBOL?).

- formerly david.thompson1 || achar(64) || worldnet.att.net
 
A

arnuld

Oh, good spot. I *showed* him how to do this. It didn't occur to me to
check that he had bothered to listen. Sheesh, furrfu, etc.


I *did* bother to listen. The only problem is using array subscripting
kills my ability to understand pointers. I think a C newbie needs to use
lots of pointers if he wants to understand them. Thats why I am not using
array subscripting.



Another good spot.

Again, I showed him how to do this properly. Perhaps he has reading
difficulties?


I have array and pointer understanding difficulties. No normal
difficulties in reading English.
 
A

arnuld

I had a quick look through, and noticed one thing: in the event of a
realloc failure, you return an error code which indicates that the parsing
was incomplete because the memory block could not be re-sized. That's
fine, but it would be pleasant if the caller were able to attempt to
recover, and you can help with this goal by null-terminating the string
before returning (which means that you need to choose to resize just
*before* you run out of memory, as you'll need one place for the
terminator).

That's fixed now.
 
B

Ben Bacarisse

arnuld said:
How about adding idx = 0; after new_mem line ?

That will not make the memory allocation any bigger. It is more
usual just keep track of the current size and double it every time
you run out of space.
you pointed it out in get_words code but this function you quoted is
get_single_word.

Yes, I forgot that. The idea is exactly the same though.
ppc is the pointer to pointer to char that you get from
function argument, which will be passed to free() in main().

Yes, I get that but not why you are telling me this! You seem to
understand and fix the leak below.
pw_begin is
used to put input characters into the array. so both ppc and pw_begin need
to point to new_mem. right ?

No. *ppc (that was a typo right?) must always point to the memory
that needs to be freed (in main or wherever). new_mem point to a
bigger buffer already partially filled with characters or to null if
realloc fails. pw_begin (not a good name) point to where the next
character is to be stored.

*ppc should get set to new_mem only when realloc does not return NULL
or you leak memory. That is now done.

pw_begin must be set to where the next character is to go, not to
new_mem. new_mem (if not NULL) already has some characters in it.
pw_begin must point as far into new_men as it does into the old buffer
so I would write something like this:

new_mem = realloc(...);
if (new_mem) {
pw_begin = new_mem + (pw_being - *ppc);
*ppc = new_mem;
}
okay, I have added an else statement aligning with if clause.
Great.


I really did not understand what you mean. I mean, i am unable to
comprehend what you said. This is my new code with buggy output:

Your checks for when you had run out of space were wrong. That is all
I meant. You could write outside of the memory you had allocated (and
you still can).

Off-topic bit:
valgrind is a superb tool for checking these things. I can't praise
it highly enough. You will find and fix more simple bugs, faster, by
using valgrind than using any other method except clear thinking and
we all find clear thinking about pointers and offsets and indexes hard
at times.
/* A program that takes a single word from input
* it uses a while loop and dynamic memory allocation to take
* continuous input form user
*
* VERSION: 1.1
*
*/


#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>


enum { WORD_SIZE = 3 };
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);
}


return 0;
}




int get_single_word( char** ppc )
{
unsigned idx;
int ch;
size_t arr_size;
char* pw_begin;
char* new_mem;

arr_size = WORD_SIZE;


*ppc = malloc(arr_size * sizeof(**ppc));
pw_begin = *ppc;


if( NULL == ppc )
{
return GSW_ENOMEM;

}


while( (EOF != (ch = getchar())) && isspace(ch) )
{
continue; /* trailing whitespace */
}


if( EOF != ch )
{
*pw_begin++ = ch;
}


for( idx = 0; (EOF != (ch = getchar())) && (! isspace(ch)); ++idx )
{
if( (WORD_SIZE - 1) == idx ) /* -1 for '\0' character*/

This is still off by one. One solution, since you already have one
character in the buffer, is to start with idx = 1 not 0.
{
new_mem = realloc( *ppc, (2 * WORD_SIZE * sizeof **ppc) );

This still needs fixing. You already have arr_size. You must have
been planning to use to grow the array!
if( NULL == new_mem )
{
*pw_begin = '\0';
return GSW_ENORESIZE;
}
else
{
pw_begin = *ppc = new_mem;
idx = 0;

See above for how to set pw_begin. Setting idx = 0 is not enough to
allocate more space the next time we run out and if you track the size
with arr_size you don't need to reset idx at all!
}
}

*pw_begin++ = ch;
}


*pw_begin = '\0';

return GSW_OK;
}

You are very close to getting this done. Just a couple of bugs remain.
 
L

lawrence.jones

David Thompson said:
But since C was not originally envisioned/expected to be used for very
extensive text or string processing, I think the decision was more
(mostly) what was easy and fast to _implement_.

Not according to DMR <http://cm.bell-labs.com/cm/cs/who/dmr/chist.html>:

In BCPL, the first packed byte contains the number of characters
in the string; in B, there is no count and strings are
terminated by a special character, which B spelled `*e'. This
change was made partially to avoid the limitation on the length
of a string caused by holding the count in an 8- or 9-bit slot,
and partly because maintaining the count seemed, in our
experience, less convenient than using a terminator.
 
A

arnuld

No. *ppc (that was a typo right?) must always point to the memory
that needs to be freed (in main or wherever). new_mem point to a
bigger buffer already partially filled with characters or to null if
realloc fails. pw_begin (not a good name) point to where the next
character is to be stored.


Now I understood why those pointers actually exist.

pw_begin must be set to where the next character is to go, not to
new_mem. new_mem (if not NULL) already has some characters in it.
pw_begin must point as far into new_men as it does into the old buffer
so I would write something like this:

new_mem = realloc(...);
if (new_mem) {
pw_begin = new_mem + (pw_being - *ppc);
*ppc = new_mem;
}


Thanks a lot for this code. It made me understand many things :)


Your checks for when you had run out of space were wrong. That is all
I meant. You could write outside of the memory you had allocated (and
you still can).

Throw away the old code. See below for my new code, with change in the
names of variables to make things clearer. See if you see any bugs.

Off-topic bit:
valgrind is a superb tool for checking these things. I can't praise it
highly enough. You will find and fix more simple bugs, faster, by using
valgrind than using any other method except clear thinking and we all
find clear thinking about pointers and offsets and indexes hard at
times.

I will put it my arsenal ;)



#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);
}


return 0;
}




int get_single_word( char** ppc )
{
unsigned ele_num;
int ch;
size_t word_length, word_length_interval;
char* word_begin;
char* new_mem;

ele_num = 0;

word_length = WORD_SIZE;
word_length_interval = 2;



*ppc = malloc(word_length * sizeof(**ppc));
word_begin = *ppc;


if( NULL == ppc )
{
return GSW_ENOMEM;

}


while( (EOF != (ch = getchar())) && isspace(ch) )
{
continue; /* trailing 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 **ppc) );
*ppc = 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;
}
 
B

Barry Schwarz

#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);
}

Since get_single_word allocated memory for you, you should free it
here.
return 0;
}




int get_single_word( char** ppc )
{
unsigned ele_num;
int ch;
size_t word_length, word_length_interval;
char* word_begin;
char* new_mem;

ele_num = 0;

word_length = WORD_SIZE;
word_length_interval = 2;

You certainly like to waste horizontal space. One blank line between
sections of code is almost always sufficient.
*ppc = malloc(word_length * sizeof(**ppc));
word_begin = *ppc;


if( NULL == ppc )
{
return GSW_ENOMEM;

And should never be used here.
}


while( (EOF != (ch = getchar())) && isspace(ch) )
{
continue; /* trailing whitespace */

Leading whitespace, not trailing.
}


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 **ppc) );
*ppc = new_mem;

The purpose of new_mem is to allow you to deal with the old allocated
block of memory when realloc fails. By immediately assigning new_mem
to *ppc, you have deleted that capability. Since you repeat this
assignment 5 lines down, I think this is residual code you forgot to
delete.
if( new_mem )
{
word_begin = new_mem + (word_begin - *ppc);

And with the previous assignment to *ppc the parenthetical expression
will invoke undefined behavior whenever realloc returns a different
address (actually moves the data to a new block of memory).
 
A

arnuld

arnuld wrote:
while( (GSW_OK == get_single_word(&pword)) && ( *pword != 0) )
{
printf("You entered: [%s]\n", pword);
}

Since get_single_word allocated memory for you, you should free it
here.


eech... my mistake. Why I always forget the free()


You certainly like to waste horizontal space. One blank line between
sections of code is almost always sufficient.

ok

And should never be used here.

why can't I return at this time ?

Leading whitespace, not trailing.
ouch!
The purpose of new_mem is to allow you to deal with the old allocated
block of memory when realloc fails. By immediately assigning new_mem to
*ppc, you have deleted that capability. Since you repeat this
assignment 5 lines down, I think this is residual code you forgot to
delete.

hey.. thats a typo, though big one ;)
 
B

Barry Schwarz

arnuld wrote:
while( (GSW_OK == get_single_word(&pword)) && ( *pword != 0) )
{
printf("You entered: [%s]\n", pword);
}

Since get_single_word allocated memory for you, you should free it
here.


eech... my mistake. Why I always forget the free()


You certainly like to waste horizontal space. One blank line between
sections of code is almost always sufficient.
ok



And should never be used here.

why can't I return at this time ?

The return is fine. I was referring to the blank line between the
return and the }.
 
A

arnuld

I had a quick look through, and noticed one thing: in the event of a
realloc failure, you return an error code which indicates that the parsing
was incomplete because the memory block could not be re-sized. That's
fine, but it would be pleasant if the caller were able to attempt to
recover, and you can help with this goal by null-terminating the string
before returning (which means that you need to choose to resize just
*before* you run out of memory, as you'll need one place for the
terminator).

Apart from that, my quick glance didn't reveal anything particularly
untoward.


okay here is my pseudo-C-code for the complete program:



int main( void )
{
char* pword;
size_t words_count;
int sort_ret;


words_count = get_input( &pword );

if( words_count )
{
sort_ret = sort_input( &pword );

if( (! sort_ret ))
{
printf_input( &pword );
}
}


free(&pword);


return 0;
}



void print_words( char **ppc )
{
printf("---------------------------------------\n\n");

while( **ppc )
{
printf("%c\n", **ppc++);
}
}

int sort_input( char **ppc )
{
/* sort words using std. lib. qsort()
if( sort_succeeds )
{
return 0;
}
else
{
return 1;
}
*/
}

void get_input( char** ppc )
{
int ret_value;

ret_value = GSW_OK;


while( (ret_value == get_single_word(&ppc)) && ( *ppc != 0) )
{
;
}

printf("get_word done");

}



I have 2 points to notice here:

1) Isn't main() little messy ?
2) design of the program requires get_single_input to take a ***
indirection.
 
C

Chris Dollin

arnuld wrote:

(fx:snip)
okay here is my pseudo-C-code for the complete program:
int main( void )
{
char* pword;
size_t words_count;
int sort_ret;


words_count = get_input( &pword );

if( words_count )
{
sort_ret = sort_input( &pword );

if( (! sort_ret ))
{
printf_input( &pword );
}
}


free(&pword);


return 0;
}
(fx:snip)

I have 2 points to notice here:

1) Isn't main() little messy ?

Stripping blank lines and variables which IMAO don't
have enough ROI gets us:

int main( void )
{
char* pword;
size_t words_count = get_input( &pword );
if(words_count)
{
if(!sort_input( &pword ))
{
printf_input( &pword );
}
}
free( &pword );
return 0;
}

And then discarding clutterbraces [1] and de-notting and
collapsing the two `if`s into one `if` and an `&&` we get:

int main( void )
{
char* pword;
size_t words_count = get_input( &pword );
if(words_count && sort_input( &pword ) == 0) printf_input( &pword );
free( &pword );
return 0;
}

/Now/ it's not (so) messy.

(I haven't paid any attention to all to the code outside `main`.)

[1] Those who don't think they're clutter don't, of course.
 
B

Barry Schwarz

okay here is my pseudo-C-code for the complete program:



int main( void )
{
char* pword;
size_t words_count;
int sort_ret;


words_count = get_input( &pword );

Down below get_input returns void.
if( words_count )
{
sort_ret = sort_input( &pword );

if( (! sort_ret ))
{
printf_input( &pword );
}
}


free(&pword);


return 0;
}



void print_words( char **ppc )
{
printf("---------------------------------------\n\n");

while( **ppc )
{
printf("%c\n", **ppc++);
}
}

int sort_input( char **ppc )
{
/* sort words using std. lib. qsort()
if( sort_succeeds )
{
return 0;
}
else
{
return 1;
}
*/
}

void get_input( char** ppc )
{
int ret_value;

ret_value = GSW_OK;


while( (ret_value == get_single_word(&ppc)) && ( *ppc != 0) )
{
;
}

printf("get_word done");

}



I have 2 points to notice here:

1) Isn't main() little messy ?
2) design of the program requires get_single_input to take a ***
indirection.

Since you haven't shown the function we can't tell. However, I expect
the function would work with a char** and you could remove the & from
the call argument.
 
A

arnuld

Since you haven't shown the function we can't tell. However, I expect
the function would work with a char** and you could remove the & from
the call argument.

If i remove it, I get Segfault right there
 
B

Ben Bacarisse

arnuld said:
If i remove it, I get Segfault right there

Did you remove it and make the correct adjustments elsewhere? Without
code we can't know what is happening.
 
A

arnuld

Did you remove it and make the correct adjustments elsewhere? Without
code we can't know what is happening.


okay, here is the code which runs fine. DO you see any hidden bugs ?



/* A program that will ask the user for input and then will sort the input alphabetically
and will print it on stdout

* As of now it does not sort any words but it will very soon. I am writing it in parts
* when parts work fine,then we put them in one place :)

* Since I did not want to put any limitation on input size in this program, I have used
* dynamic memory allocation to solve the problem. My intent in creating and then solving
* this problem was purely of C learning (as defined by ANSI standard) and nothign else. I
* wanted to learn C and hence this problem and quite heavy discussion of it on comp.lang.c.
* I owe many thanks to the brillant help I got in comp.lang.c
*
* VERSION 1.0
*
*
*/


#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>


enum { WORD_SIZE = 3 };
enum { GSW_OK, GSW_ENOMEM, GSW_ENORESIZE } ;


void print_input( char** );
size_t get_input( char** );
int get_single_word( char** );



int main( void )
{
char* pword;
size_t words_count;


words_count = get_input( &pword );

printf("words_count = %u\n", words_count);



return 0;
}




void print_words( char **ppc )
{
printf("---------------------------------------\n\n");

while( **ppc )
{
printf("%c\n", **ppc++);
}
}




size_t get_input( char** pword )
{
size_t w_cnt;

w_cnt = 0;
while( (GSW_OK == get_single_word(pword)) && ( **pword != 0) )
{
printf("You entered: [%s]\n", *pword);
++w_cnt;
free( *pword );
}


return w_cnt;
}




int get_single_word( char** ppc )
{
unsigned ele_num;
int ch;
size_t word_length, word_length_interval;
char* word_begin;
char* new_mem;

ele_num = 0;

word_length = WORD_SIZE;
word_length_interval = 2;

*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;
}
 
C

Chad

On Thu, 25 Sep 2008 11:51:59 +0100, Ben Bacarisse wrote:
Did you remove it and make the correct adjustments elsewhere? Without
code we can't know what is happening.

okay, here is the code which runs fine. DO you see any hidden bugs ?

/* A program that will ask the user for input and then will sort the input alphabetically
and will print it on stdout

* As of now it does not sort any words but it will very soon. I am writing it in parts
* when parts work fine,then we put them in one place :)

* Since I did not want to put any limitation on input size in this program, I have used
* dynamic memory allocation to solve the problem. My intent in creating and then solving
* this problem was purely of C learning (as defined by ANSI standard) and nothign else. I
* wanted to learn C and hence this problem and quite heavy discussion of it on comp.lang.c.
* I owe many thanks to the brillant help I got in comp.lang.c
*
* VERSION 1.0
*
*
*/

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

enum { WORD_SIZE = 3 };
enum { GSW_OK, GSW_ENOMEM, GSW_ENORESIZE } ;

void print_input( char** );
size_t get_input( char** );
int get_single_word( char** );

int main( void )
{
char* pword;
size_t words_count;

words_count = get_input( &pword );

printf("words_count = %u\n", words_count);

return 0;

}

void print_words( char **ppc )
{
printf("---------------------------------------\n\n");

while( **ppc )
{
printf("%c\n", **ppc++);
}

}

size_t get_input( char** pword )
{
size_t w_cnt;

w_cnt = 0;
while( (GSW_OK == get_single_word(pword)) && ( **pword != 0) )
{
printf("You entered: [%s]\n", *pword);
++w_cnt;
free( *pword );
}

return w_cnt;

}

Maybe I'm wrong, but since get_single_word() takes char**, shouldn't
you be passing &pword instead of pword?
 
R

Richard

Chad said:
On Thu, 25 Sep 2008 11:51:59 +0100, Ben Bacarisse wrote:
Did you remove it and make the correct adjustments elsewhere? Without
code we can't know what is happening.

okay, here is the code which runs fine. DO you see any hidden bugs ?

/* A program that will ask the user for input and then will sort the input alphabetically
and will print it on stdout

* As of now it does not sort any words but it will very soon. I am writing it in parts
* when parts work fine,then we put them in one place :)

* Since I did not want to put any limitation on input size in this program, I have used
* dynamic memory allocation to solve the problem. My intent in creating and then solving
* this problem was purely of C learning (as defined by ANSI standard) and nothign else. I
* wanted to learn C and hence this problem and quite heavy discussion of it on comp.lang.c.
* I owe many thanks to the brillant help I got in comp.lang.c
*
* VERSION 1.0
*
*
*/

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

enum { WORD_SIZE = 3 };
enum { GSW_OK, GSW_ENOMEM, GSW_ENORESIZE } ;

void print_input( char** );
size_t get_input( char** );
int get_single_word( char** );

int main( void )
{
char* pword;
size_t words_count;

words_count = get_input( &pword );

printf("words_count = %u\n", words_count);

return 0;

}

void print_words( char **ppc )
{
printf("---------------------------------------\n\n");

while( **ppc )
{
printf("%c\n", **ppc++);
}

}

size_t get_input( char** pword )
{
size_t w_cnt;

w_cnt = 0;
while( (GSW_OK == get_single_word(pword)) && ( **pword != 0) )
{
printf("You entered: [%s]\n", *pword);
++w_cnt;
free( *pword );
}

return w_cnt;

}

Maybe I'm wrong, but since get_single_word() takes char**, shouldn't
you be passing &pword instead of pword?

"size_t get_input( char** pword )"
 
C

Chad

Chad said:
On Thu, 25 Sep 2008 11:51:59 +0100, Ben Bacarisse wrote:
Did you remove it and make the correct adjustments elsewhere? Without
code we can't know what is happening.
okay, here is the code which runs fine. DO you see any hidden bugs ?
/* A program that will ask the user for input and then will sort the input alphabetically
and will print it on stdout
* As of now it does not sort any words but it will very soon. I am writing it in parts
* when parts work fine,then we put them in one place :)
* Since I did not want to put any limitation on input size in this program, I have used
* dynamic memory allocation to solve the problem. My intent in creating and then solving
* this problem was purely of C learning (as defined by ANSI standard) and nothign else. I
* wanted to learn C and hence this problem and quite heavy discussion of it on comp.lang.c.
* I owe many thanks to the brillant help I got in comp.lang.c
*
* VERSION 1.0
*
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
enum { WORD_SIZE = 3 };
enum { GSW_OK, GSW_ENOMEM, GSW_ENORESIZE } ;
void print_input( char** );
size_t get_input( char** );
int get_single_word( char** );
int main( void )
{
char* pword;
size_t words_count;
words_count = get_input( &pword );
printf("words_count = %u\n", words_count);
return 0;
}
void print_words( char **ppc )
{
printf("---------------------------------------\n\n");
while( **ppc )
{
printf("%c\n", **ppc++);
}
}
size_t get_input( char** pword )
{
size_t w_cnt;
w_cnt = 0;
while( (GSW_OK == get_single_word(pword)) && ( **pword != 0) )
{
printf("You entered: [%s]\n", *pword);
++w_cnt;
free( *pword );
}
return w_cnt;
}
Maybe I'm wrong, but since get_single_word() takes char**, shouldn't
you be passing &pword instead of pword?

"size_t get_input( char** pword )"


Huh? On


size_t get_input( char** pword )

he passes &pword.

Yet, on


int get_single_word( char** ppc )

he passes pword.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,997
Messages
2,570,240
Members
46,828
Latest member
LauraCastr

Latest Threads

Top