469,314 Members | 2,224 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,314 developers. It's quick & easy.

Any way to take a word as input from stdin ?

I searched the c.l.c archives provided by Google as Google Groups with
"word input" as the key words and did not come up with anything good.
C++ has std::string for taking a word as input from stdin. C takes input
in 2 ways:

1) as a character, etchar()
2) as a whole line, fgets()
as C programmer, are we supposed to create a get_word function everytime
when we need a words as input from stdin ( e.g. terminal)
--
www.lispmachine.wordpress.com
my email is @ the above blog.
Google Groups is Blocked. Reason: Excessive Spamming

Sep 10 '08
209 7565
arnuld <su*****@invalid.addresswrites:
>On Mon, 29 Sep 2008 11:18:54 +0100, Ben Bacarisse wrote:

>This is not an outline for the design you explained. This is very
similar to what you posted before -- the get_input function prints the
words.

Thats just there unintentionally, for a memory check. I will remove
it.
Please do, or mark it like this:

#ifdef DEBUG
....
#endif

so we know it is not what you are really trying to do.
>I thought you wanted get_input to store them all in a dynamic
array and "return" that (return in quotes because the plan was for a
status code to be the actual return values --


*Exactly* that..
OK...
>the array would be a char *** parameter).

yes, but then get_single_word() will take a char*** as argument.
No. A function takes what it must due to its design.
get_single_word() needs a char ** because its job is to set a char *
that "does not belong to it". It is passed a pointer to the char *
that is must set: get_single_word(char **);

Giving get_input() a char *** parameter does not mean that this must be
passed to get_single_word. You get to say what you pass!

--
Ben.
Sep 29 '08 #201
On 2008-09-29, arnuld <su*****@invalid.addresswrote:
>On Mon, 29 Sep 2008 11:18:54 +0100, Ben Bacarisse wrote:
>the array would be a char *** parameter).

yes, but then get_single_word() will take a char*** as argument. When I try to
do that I get invalid pointer error. I have to admit that this busines of
pointers is really hell confusing. get_words() is already getting the address of
the pointer then why have to pass the address of the address of the
pointer to get_single_word(). Even when I do that my program compiles
fine but ends in doing semantic error. Program exits as soon as you input
one word.
Since get_single_word() needs to return a pointer to a string (char *),
and does so "by reference", its parameter should be a char **. No more
indirection is necessary.
2nd, someone told me on clc that if a function crosses 40 lines then
alarms should be ringing. get_single_word() is a 60 line function. Does
it need to be abstracted into 2 other functions ?
Probably. Your style uses more vertical space than most, though, so
any line-count-related rules of thumb need to be adjusted for that.
Input functions are usually very short, 10 or 15 lines plus whatever
validation is necessary.
>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
enum { WORD_SIZE = 3, WORD_ERR = -1 };
enum { GSW_OK, GSW_ENOMEM, GSW_ENORESIZE } ;
enum { GI_OK = 0 , GI_ERR = WORD_ERR };
int get_words( char**, size_t* );
int get_single_word( char*** );

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

pword = NULL;
words_count = 0;
input_err = WORD_ERR; /* we will update the status in function
call to get_input() */
Do you not like initializing at declaration? It seems to me it would
be clearer to do so. (nb I wrapped your comment to fit in one line.)
input_err = get_words( &pword, &words_count );

if( WORD_ERR != input_err )
{
printf("words_count = %u\n", words_count);
}
size_t might be a different size than unsigned int, so you need to
cast it or use the %z specifier introduced in C99.
>
/* call to - sort_input(...)
call to - printf_input(...) */

free( pword );
return 0;
}
main() is fine other than those two minor nits.
>

int get_words( char** pword, size_t* w_cnt )
This seems suspicious - if get_words() needs to return a list of
strings, the required type is char ***. (Pointer to 'array' of
pointers to strings.)
{
int err_catcher;
*w_cnt = 0;
while( (err_catcher = get_single_word(&pword)) && ( **pword != 0) )
And then here you would pass *pword++, which gives get_single_word
a char ** to redirect to a string, and increments pword to point
to the next available item in the list.
{
if( GSW_OK == err_catcher )
{
++*w_cnt;
}
else
{
return GI_ERR;
}
}

return GI_OK;
}


int get_single_word( char*** ppc )
If you look, you find that you always refer to ppc with **ppc, which
suggests that a level of indirection can be removed.
{
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 == word_begin )
{
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;
}
This whole loop needs to be redone using my suggestions, as well as those of
other posters.
>
*word_begin = '\0';

return GSW_OK;
}

--
Andrew Poelstra ap*******@wpsoftware.net
Only GOD may divide by zero. That is how he created black holes.
-Veselin Jungic
Sep 29 '08 #202
On Mon, 29 Sep 2008 15:16:56 +0100, Ben Bacarisse wrote:

Please do, or mark it like this:

#ifdef DEBUG
...
#endif

so we know it is not what you are really trying to do.

okay.

No. A function takes what it must due to its design.
get_single_word() needs a char ** because its job is to set a char *
that "does not belong to it". It is passed a pointer to the char *
that is must set: get_single_word(char **);

Giving get_input() a char *** parameter does not mean that this must be
passed to get_single_word. You get to say what you pass!

Thanks so much for the technical advice. I will take some time to write
some pseudo code again to get done with the design of the functions first.
I will make a new post with my new pseudo code and discussion of
function design.

--
www.lispmachine.wordpress.com
my email is @ the above blog.
Gooogle Groups is Blocked. Reason: Excessive Spamming

Sep 30 '08 #203
On Mon, 29 Sep 2008 12:28:59 +0000, James Kuyper wrote:
What does that have to do with it? what you pass to feof() and ferror()
is not the value returned by the I/O function. What you pass it is the
FILE* associated with the stream that you are using the I/O function on.
The getchar() function is exactly equivalent to getc(stdin); it's
provided as a separate function from getc() only for convenience. All
you need to do is check feof(stdin) and ferror(stdin).
I can't, that input character is needed by the program, hence I use ch to
store it. If i use feof(stdin) then I will loose the input and will get
only the integer vale returned by feof or ferror. The input character is
needed because we are storing them


--
www.lispmachine.wordpress.com
my email is @ the above blog.
Gooogle Groups is Blocked. Reason: Excessive Spamming

Sep 30 '08 #204
On 30 Sep, 06:17, arnuld <sunr...@invalid.addresswrote:
On Mon, 29 Sep 2008 12:28:59 +0000, James Kuyper wrote:
What does that have to do with it? what you pass to feof() and ferror()
is not the value returned by the I/O function. What you pass it is the
FILE* associated with the stream that you are using the I/O function on.
The getchar() function is exactly equivalent to getc(stdin); it's
provided as a separate function from getc() only for convenience. All
you need to do is check feof(stdin) and ferror(stdin).

I can't, that input character is needed by the program, hence I use ch to
store it. If i use feof(stdin) then I will loose the input and will get
only the integer vale returned by feof or ferror.
I'm baffled. Why will you "lose the input"? What does this mean.
The input character is
needed because we are storing them
what?
int read_char_and_check (FILE* f)
{
char ch;
ch = getc (f);
if (ch == EOF)
{
if (feof(f))
printf ("end-of-file\n");
else
printf ("error reading file\n");
}
return ch;
}

--
Nick Keighley

Governments, like diapers, must be changed often,
and for the same reason.
Sep 30 '08 #205
arnuld wrote:
>On Mon, 29 Sep 2008 12:28:59 +0000, James Kuyper wrote:
>What does that have to do with it? what you pass to feof() and ferror()
is not the value returned by the I/O function. What you pass it is the
FILE* associated with the stream that you are using the I/O function on.
The getchar() function is exactly equivalent to getc(stdin); it's
provided as a separate function from getc() only for convenience. All
you need to do is check feof(stdin) and ferror(stdin).

I can't, that input character is needed by the program, hence I use ch to
store it. If i use feof(stdin) then I will loose the input and will get
only the integer vale returned by feof or ferror. The input character is
needed because we are storing them
What are you talking about? Just replace feof(ch) with feof(stdin);
there's no reason why doing so would require you to make any changes to
the line where you write ch=getchar().

Sep 30 '08 #206
On Sep 30, 11:12 am, Nick Keighley <nick_keighley_nos...@hotmail.com>
wrote:
>
int read_char_and_check (FILE* f)
{
char ch;
ch = getc (f);
That's implementation defined, if char is signed and EOF < SCHAR_MIN
or if a value greater than SCHAR_MAX is returned.
if (ch == EOF)
{
if (feof(f))
printf ("end-of-file\n");
else
printf ("error reading file\n");
It doesn't have to be an error. Assuming char is unsigned, EOF == -1,
you'd get the same results for reading UCHAR_MAX and EOF.
}
return ch;
}
It's possible that this return value is never equal to EOF, even if ch
== EOF

Sep 30 '08 #207
On 30 Sep, 09:12, Nick Keighley <nick_keighley_nos...@hotmail.com>
wrote:
On 30 Sep, 06:17, arnuld <sunr...@invalid.addresswrote:
On Mon, 29 Sep 2008 12:28:59 +0000, James Kuyper wrote:
What does that have to do with it? what you pass to feof() and ferror()
is not the value returned by the I/O function. What you pass it is the
FILE* associated with the stream that you are using the I/O function on.
The getchar() function is exactly equivalent to getc(stdin); it's
provided as a separate function from getc() only for convenience. All
you need to do is check feof(stdin) and ferror(stdin).
I can't, that input character is needed by the program, hence I use ch to
store it. If i use feof(stdin) then I will loose the input and will get
only the integer vale returned by feof or ferror.

I'm baffled. Why will you "lose the input"? What does this mean.
The input character is
needed because we are storing them

what?

int read_char_and_check (FILE* f)
{
* * char ch;
int ch; /* doh! */
* * ch = getc (f);
* *if (ch == EOF)
* *{
* * * *if (feof(f))
* * * * * *printf ("end-of-file\n");
* * * *else
* * * * * *printf ("error reading file\n");
* *}
* *return ch;

}

--
Nick Keighley

Governments, like diapers, must be changed often,
and for the same reason.
Sep 30 '08 #208
On Tue, 30 Sep 2008 10:17:10 +0500, arnuld <su*****@invalid.address>
wrote:
>On Mon, 29 Sep 2008 12:28:59 +0000, James Kuyper wrote:
>What does that have to do with it? what you pass to feof() and ferror()
is not the value returned by the I/O function. What you pass it is the
FILE* associated with the stream that you are using the I/O function on.
The getchar() function is exactly equivalent to getc(stdin); it's
provided as a separate function from getc() only for convenience. All
you need to do is check feof(stdin) and ferror(stdin).

I can't, that input character is needed by the program, hence I use ch to
store it. If i use feof(stdin) then I will loose the input and will get
only the integer vale returned by feof or ferror. The input character is
needed because we are storing them
You seem to think that feof or ferror perform some action against the
data in the stream. That is not true. They merely test and report
the status of certain indicators associated with the stream.

--
Remove del for email
Sep 30 '08 #209
jellybean stonerfish <st********@geocities.comwrites:
On Thu, 18 Sep 2008 22:46:07 +0500, arnuld wrote:
You are wrong. Most Indian students say that you need Windows to run a
computer, without Windows you can not use a computer. I have yet to meet
a person who uses Linux as his daily use OS.


Off topic, but what the hell. I, living in Southern California, have yet
to meet anybody who uses linux. Besides myself, and people I have given
computers to. I work in construction, and have been in many offices, and
have seen nothing but window and mac boxes. Eventually, if my children
let me have some free time, I will join a LUG.
Linux is alive and well in Pasadena and the San Gabriel Valley.
Check SGVLUG - in fact there is a meeting tomorrow night (the
second Thursday of each month), and drop-ins are welcome.
Oct 9 '08 #210

This discussion thread is closed

Replies have been disabled for this discussion.

By using this site, you agree to our Privacy Policy and Terms of Use.