problem with getchar

S

shekhardeodhar

The program compiles properly (most of it is from k&r) but the second
function (here character_count) gives wrong answer.
Can someone please explain why ?


#include<stdio.h>
#define IN 1
#define OUT 0

int word_count();
int character_count();

int
main(void)
{
printf("%d\n",word_count());
printf("%d\n",character_count());

return 0;
}

int
word_count ()
{

int c, nw, state;
state = OUT;
nw = 0;

while ((c = getchar ()) != EOF) {
if (c == ' ' || c == '\n' || c == '\t')
state = OUT;
else if (state == OUT) {
state = IN;
++nw;
}
}

return nw ;
}


int
character_count ()
{
int c;
int nc = 0;
while ((c = getchar ()) != EOF)
++nc;
return nc;
}
 
K

kleuske

(e-mail address removed) schreef:
The program compiles properly (most of it is from k&r) but the second
function (here character_count) gives wrong answer.

What answer is required?
Can someone please explain why ?

getchar reads one character from stdin.

<snip>
int wc = 0; /* word count */
int cc = 0; /* character count */
int
main(void)
{ count();
printf("%d\n",wc);
printf("%d\n",cc);

both word_count() and character_count() call get_char independently.
Hence they operate on two totally different sequences. If this is
required, than it's ok. If both should operate on the _same_ sequence,
this is a serious problem.
return 0;
}
void
count (void)
{

int c, nw, state;
state = OUT;
nw = 0;

It's good to see you practice FSM's. There may be easier ways to do it,
though.
while ((c = getchar ()) != EOF) {
if (c == ' ' || c == '\n' || c == '\t') {
state = OUT; }
else if (state == OUT) {
state = IN;
++wc;
++cc;
 
M

Michael Mair

The program compiles properly (most of it is from k&r) but the second
function (here character_count) gives wrong answer.

What did you give as input? What did you expect? What did you get?

Can someone please explain why ?

In theory, it is perfectly possible that EOF is sticky for stdin,
so you would have to clear it before using character_count().
Did you test character_count() without preceding word_count()?
#include<stdio.h>
#define IN 1
#define OUT 0

int word_count();
int character_count();

int
main(void)
{
printf("%d\n",word_count());
printf("%d\n",character_count());

return 0;
}

Using
int
main (void)
{
printf("%d\n",character_count());

return 0;
}
on an input of "a bb ccc\ndddd eeeee ffffff\n" gives the
expected answer.
Maybe there is some conceptual problem on your part: If you
want to count the characters and words of _one_ set of inputs,
you either have to first read all the input and provide it as
argument to counting functions or you have to count everything
in one function as you read it (i.e. read a character with
getchar() and adjust _all_ counters as necessary).
int
word_count ()
{

int c, nw, state;
state = OUT;

Note: As you use the states IN and OUT only here, it may be
better to restrict their "visibility":
enum {OUT, IN};
state = OUT;
nw = 0;

while ((c = getchar ()) != EOF) {
if (c == ' ' || c == '\n' || c == '\t')
state = OUT;
else if (state == OUT) {
state = IN;
++nw;
}
}

return nw ;
}
int
character_count ()
{
int c;
int nc = 0;
while ((c = getchar ()) != EOF)
++nc;
return nc;
}

This looks fine to me.

Cheers
Michael
 
M

Michael Mair

(e-mail address removed) schreef:
int wc = 0; /* word count */
int cc = 0; /* character count */

How is inducing the OP to use file scope identifiers with
extern linkage (vulgo: "globals") helpful?
both word_count() and character_count() call get_char independently.
Hence they operate on two totally different sequences. If this is
required, than it's ok. If both should operate on the _same_ sequence,
this is a serious problem.
True.


void
count (void)

It's good to see you practice FSM's. There may be easier ways to do it,
though.

FSM is no "recognized TLA" around here, so some people may
wonder about religious exercises... ;-)

How is that supposed to work? Your correction makes wc and cc
effectively the same. You probably meant:
++cc;
if (c == ' ' || c == '\n' || c == '\t') {
state = OUT;
}
else if (state == OUT) {
state = IN;
++wc;
}
However, there is still the exceedingly ugly use of file scope
wc and cc.


Cheers
Michael
 
K

keltanokka

Hei

Just a beginner so I won't try to give any kind of technical reply.

If you change your code a little and add a printf statement to the body
of the while
statement in the function character_count you should get a clue as to
what is happening.
Something like this should do.

while ((c = getchar ()) != EOF){
printf ("The value of c is %d\n", c);
++nc;
}

The problem can be solved with the following:

while ((c = getchar ()) != EOF){
getchar(); /* Seems to eat up that newline character */
++nc;
}

As I said at the start I am just a beginner and there maybe a better
solution to the
problem that you face.

Take care.

t. ir
 
M

Michael Mair

Please do not top-post.
Quote enough of the previous message(s) to provide sufficient
context and write your own reply interspersed with that and/or
below.

[Context: Seemingly erroneous character count function]
Just a beginner so I won't try to give any kind of technical reply.

If you change your code a little and add a printf statement to the body
of the while statement in the function character_count you should
get a clue as to what is happening.
Something like this should do.

while ((c = getchar ()) != EOF){
printf ("The value of c is %d\n", c);
++nc;
}

Indeed. To be on the safe side, add fflush(stdout); if your
programme seems to "stop" at a certain point. fflush()ing an
output stream forces all remaining output to be written.
If output is terminated by a '\n' character, this happens
automatically for line-buffered streams but to be sure "when"
the whole thing is going wrong, use fflush().
The problem can be solved with the following:

while ((c = getchar ()) != EOF){
getchar(); /* Seems to eat up that newline character */
++nc;
}

You are reading two characters for every loop iteration but
increase nc only once.
This does not give the right number of characters.


Cheers
Michael
 
K

kleuske

Michael Mair schreef:
How is inducing the OP to use file scope identifiers with
extern linkage (vulgo: "globals") helpful?

I did not want to rewrite the whole thing. This is not meant to be
copied verbatim or pretend to be production code. It's merely intended
to Q&D show what's wrong.


FSM is no "recognized TLA" around here, so some people may
wonder about religious exercises... ;-)

'Xcuse me. I'll ask C3PO next time, round. FSM --> Finite State
Machine.
How is that supposed to work?

The way you suggest below. After giving him the main part of the
(probable) solution. (I still don't know what exactly the requirements
are, i left this for him to solve. You spotted it easily enough.
Your correction makes wc and cc
effectively the same. You probably meant:
++cc;
if (c == ' ' || c == '\n' || c == '\t') {
state = OUT;
}
else if (state == OUT) {
state = IN;
++wc;
}
However, there is still the exceedingly ugly use of file scope
wc and cc.

True. But I won't do _all_ his homework.
 
M

Michael Mair

Michael Mair schreef:

'Xcuse me. I'll ask C3PO next time, round. FSM --> Finite State
Machine.

Thank you; not having to guess (and misunderstand) makes live
easier in discussions.
True. But I won't do _all_ his homework.

Fair enough :)


Cheers
Michael
 
S

shekhardeodhar

Michael said:
What did you give as input? What did you expect? What did you get?

This is my first posting so maybe I was not all that precise.
I gave the input as a text file.
My problem was that the first function works but the second does
not(independently both of them work i.e only if one of them is used it
works)
 
C

CBFalconer

shekhardeodhar said:
This is my first posting so maybe I was not all that precise.
I gave the input as a text file.
My problem was that the first function works but the second does
not(independently both of them work i.e only if one of them is
used it works)

You have two function operating on stdin. The first operates until
stdin has been read to EOF. When you call the second, the input
file is still at EOF, so it reads nothing.

You don't want to get into any nonsense about rewinding, because in
addition to being a nuisance it may not be possible (think
interactive input). So read the input once and draw conclusions.
Somewhere you can have something like:

while (EOF != (ch = getchar())) {
chcount++;
if (isspace(ch)) state = OUT;
else if (OUT == state) {
state = IN;
wdcount++;
}
}

Now you have to worry about where to declare and initialize, and
how to return, the values of chcount and wdcount.

--
Some informative links:
http://www.geocities.com/nnqweb/
http://www.catb.org/~esr/faqs/smart-questions.html
http://www.caliburn.nl/topposting.html
http://www.netmeister.org/news/learn2quote.html
 
K

Keith Thompson

Michael Mair said:
Please do not top-post.
Quote enough of the previous message(s) to provide sufficient
context and write your own reply interspersed with that and/or
below.

It looks like Google really has fixed the quoting problem -- but they
still leave the cursor at the *top* of the article, and they don't
provde any clue that the user should write his reply at the bottom.
We're going to be seeing a lot of top-posting.

Maybe Google will fix this after a few years of complaining.

*sigh*
 
S

spibou

Keith said:
It looks like Google really has fixed the quoting problem -- but they
still leave the cursor at the *top* of the article, and they don't
provde any clue that the user should write his reply at the bottom.
We're going to be seeing a lot of top-posting.

Maybe Google will fix this after a few years of complaining.

Actually the cursor appears at the bottom of the article on my browser.
But if the article has greater length than the size of the typing
window
then you need to scroll to the bottom of the window to see the cursor.
Presumably some users will just click at the top of the window if they
don't see a cursor.

But I don't think that all that is very relevant. Not top-posting
should
be common sense.

Spiros Bousbouras
 

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
474,470
Messages
2,571,809
Members
48,797
Latest member
PeterSimpson
Top