Puzzle!

K

Keith Thompson

Please trim quoted material when you post a followup. I particular,
don't quote singatures unless you're actually commenting on them.

(A very minor point; there's no "@" in my name.)
Actually you interpreted it wrongly. What I wanted to say was that
fflush(stdin) will flush out the whole buffer. But in this case the
buffer had only a "\n". So I wrote "fflush(stdin) just flushes out the
"\n" from the buffer".

Hope you got my point now.

The fact that fflush(stdin) invokes undefined behavior has been
pounded to death, so I won't mention it again. (Oops, I just did!)
But on a system that does define the behavior, namely Solaris, the man
page says:

Flushing an input stream discards any buffered input and adjusts
the file pointer such that the next input operation accesses the
byte after the last one read.

For input from a keyboard, that means (I think) that it discards
anything in the typeahead buffer, i.e., any characters that the user
has typed that have not yet been read by input operations. You *don't
know* that the input buffer contains only a '\n' character; it could
contain anything.

fflush(stdin) is undefined; when it is defined, it doesn't necessarily
do what you think it does.
 
K

Keith Thompson

BiGYaN said:
BiGYaN said:
[snip]

I could never imagine writing a program in C without "#include
<stdio.h>". I just did not write it as I thought it was quite obvious
to add it at the start. But I'm sorry if it caused some inconvenience
to my not-so-learned friend.

You say could never imagine it, but how are we supposed to know that?
Plenty of programmers *don't* know that the "#include <stdio.h>" is
required, and omit it in real programs. You may be a good enough
programmer that you never make that mistake yourself, but the only way
we can know that is if you demonstrate it. In this case, you
demonstrated the opposite.

You need to be just as careful with code you post here as with code
you write in the real world. The readers of this newsgroup tend to be
far more strict that most compilers, perhaps more so than any of them.

Referring to Richard Heathfield as "not-so-learned" is an error (one
that he's already taken with his usual good humor). Stick around here
for a while, and you'll see that it's very far from the truth.
As far as getchar() returning an int. Yes I know it does, but why
bother with that here. The original question asked for a solution and
I provided it. It will work fine in this case.

"It will work fine in this case" is perhaps the greatest source of
errors, some of which may have drastic consequences. getchar()
returns an int. There is *never* a good reason to assign its result
to a char.

Code you post to comp.lang.c is unlikely to be cause any problems in
the real world; nobody is going to take a code snippet posted here and
use it to run a nuclear reactor. The worst consequence, as I hope
you're seeing now, is a bit of personal embarrassment. But this is an
opportunity to develop good habits that will serve you (and your
users) very well when you write code for the real world. Don't expect
us to ignore errors because they don't matter here; this is a learning
forum, and errors matter very much.
 
R

Richard Heathfield

Keith Thompson said:

Referring to Richard Heathfield as "not-so-learned" is an error

Oh, did he mean me? I thought he was referring to the OP. Well, if he
meant me, I look forward to becoming more learnederer.
 
M

Morris Dovey

Keith Thompson wrote:

<code-specific snipage>

| You need to be just as careful with code you post here as with code
| you write in the real world. The readers of this newsgroup tend to
| be far more strict that most compilers, perhaps more so than any of
| them.

Although it's sometimes a PIA and sometimes produces a certain amount
of chagrin, it's exactly this that makes the newsgroup a valuable
resource. Nowhere else will your work ever receive a higher-quality
peer review.

| Referring to Richard Heathfield as "not-so-learned" is an error (one
| that he's already taken with his usual good humor). Stick around
| here for a while, and you'll see that it's very far from the truth.

Seconded. I'd suggest being /very/ wary of aspersing anyone here until
you absolutely know you're on solid ground. FWIW, if I ever needed to
assemble a software "dream team" for a project on which many lives
depended, nearly all of the candidates would be drawn from my list of
c.l.c regulars.

|| As far as getchar() returning an int. Yes I know it does, but why
|| bother with that here. The original question asked for a solution
|| and I provided it. It will work fine in this case.
|
| "It will work fine in this case" is perhaps the greatest source of
| errors, some of which may have drastic consequences. getchar()
| returns an int. There is *never* a good reason to assign its result
| to a char.

"Wisdom" is a word that would seem to have fallen from common usage.
One of its more important nuances involves knowledge of and
consideration for consequence based on experience. I'd encourage you
to accept the gift whenever it's offered.

| Code you post to comp.lang.c is unlikely to be cause any problems in
| the real world; nobody is going to take a code snippet posted here
| and use it to run a nuclear reactor. The worst consequence, as I
| hope you're seeing now, is a bit of personal embarrassment. But
| this is an opportunity to develop good habits that will serve you
| (and your users) very well when you write code for the real world.
| Don't expect us to ignore errors because they don't matter here;
| this is a learning forum, and errors matter very much.

Keith may be a bit optimistic here. More than just a little of the
code posted here has gone into real-world applications - although
probably not without local peer review. The rest is 24-carat truth.
 
J

Joachim Schmitz

CBFalconer said:
Because without the int declaration you can't detect EOF.
Well, to be fair: in his small sample program he wasn't looking for EOF...

Bye, Jojo
 
R

Richard Heathfield

Joachim Schmitz said:
Well, to be fair: in his small sample program he wasn't looking for
EOF...

To be even fairer, he *should* have been looking for EOF.
 
K

Keith Thompson

Richard Heathfield said:
Keith Thompson said:



Oh, did he mean me? I thought he was referring to the OP. Well, if he
meant me, I look forward to becoming more learnederer.

Looking back at the previous article, I'm not sure who he was
referring to. I read it as referring to you, but I could easily have
been mistaken.
 
J

J. J. Farrell

I could never imagine writing a program in C without "#include
<stdio.h>".

How are we supposed to know the limitations of your imagination? This
particular limitation implies a lack of wide experience.
...

As far as getchar() returning an int. Yes I know it does, but why
bother with that here.

Because it would require less typing and effort than the wrong way you
chose to do it? Because it would avoid bugs and wasted effort further
down the line when someone expands this sketch into a real program?

I'm intrigued to know why you would waste the time and effort to work
out whether or not there was any actual need to use an int in this
case, then choose to go to the extra effort of more typing to put char
instead of int. You'd have saved yourself thinking time and typing
time by just using the correct type in the first place. Doesn't seem a
very efficient way to work.
 
K

KIRAN

Some days ago, I written a mini program like this:
#include <stdio.h>

int main()
{
char c;
int n;

scanf("%d",&n);
c = getchar();

return 0;

}

I want to assign n and c specific values,for example,give n and c
values of 5 and 'x' in fact when I input 5 then "enter",the program
is finish.I know when I press "Enter", I assigned '\n' to variable c,
But how can I avoid this?
#include<stdio.h>
int main()
{
char c;
int n;

scanf("%d",&n);
fflush(stdin);
c = getchar();

return 0;

}
 
K

Keith Thompson

KIRAN said:
#include<stdio.h>
int main()
{
char c;
int n;

scanf("%d",&n);
fflush(stdin);
c = getchar();

return 0;

}

No, no, no, no, and did I mention, NO!

fflush(stdin) invokes undefined behavior. Read the lengthy
explanations of that fact in this very thread. And read questions
12.26a and 12.26b in the comp.lang.c FAQ, <http://www.c-faq.com/>.

And getchar() returns an int, not a char; that's also been discussed
at length in this thread.
 
B

Barry Schwarz

#include<stdio.h>
int main()
{
char c;
int n;

scanf("%d",&n);
fflush(stdin);

Have you made any effort to follow the thread? Do you know that
passing an input stream to fflush invokes undefined behavior?
c = getchar();

return 0;

}


Remove del for email
 
U

Urs Beeli

Keith Thompson wrote:

<code-specific snipage>

| You need to be just as careful with code you post here as with code
| you write in the real world. The readers of this newsgroup tend to
| be far more strict that most compilers, perhaps more so than any of
| them.

Although it's sometimes a PIA and sometimes produces a certain amount
of chagrin, it's exactly this that makes the newsgroup a valuable
resource. Nowhere else will your work ever receive a higher-quality
peer review.

I guess much of the bickering we get on this newsgroup comes from the
different mindset its readers have. There are those that...
| But this is an opportunity to develop good habits that will serve you
| (and your users) very well when you write code for the real world. Don't
| expect us to ignore errors because they don't matter here; this is a
| learning forum, and errors matter very much.

... appreciate this strictness and perpetual advising to use these good
habits in all code, even small samples posted to c.l.c. I count myself as
one of those, as I have learnt a lot from the nitpicking regulars advocating
safe coding in all cicumstances.

Then, there are those who are stuck on a problem (be it homework, first
steps in C, work related) who want a quick fix and are happy if it gets them
one step further, not caring about portability, undefined behaviour. To
those, being constantly admonished that their "working program" is not of
satisfactory quality to the regulars here, will most likely seem to be
annoying or even appear arrogant.

I remember may first steps in programming C, I did a lot of trial and error,
I picked up bits and pieces here and there. I can't promise that I never
fflushed(stdin), though I never used scanf (because I couldn't get it to
work, not because I found it unsafe). At the time, a quick fix would have
satisfied me.

It took me years to learn from my mistakes, to hear about and read K&R2, to
find this group and get to know about the standard. Amazingly, some of this
even happened after I took programming from a hobby to a job.

I have profited incredibly from lurking in c.l.c and becoming a nitpicker in
my own code has made it more portable, safer and easier to maintain.


I think what the regulars here sometimes forget (and I can understand why
they do) is that there are people that do not yet understand why being
strict in coding is so important and that making them understand this takes
as much patience (maybe even more) than teaching them C.

And I would hope that those that do not yet see eye to eye with the regulars
try to learn this lesson without being offended, if their mistakes are
pointed out with little empathy :)

Cheers
/urs
 
R

Richard Heathfield

Urs Beeli said:

It took me years to learn from my mistakes, to hear about and read
K&R2, to find this group and get to know about the standard.
Amazingly, some of this even happened after I took programming from a
hobby to a job.

That's not so amazing as it should be, alas.
I have profited incredibly from lurking in c.l.c and becoming a
nitpicker in my own code has made it more portable, safer and easier
to maintain.

I'm delighted to hear it. Do you want a job in clc's PR department? :)

I think what the regulars here sometimes forget (and I can understand
why they do) is that there are people that do not yet understand why
being strict in coding is so important and that making them understand
this takes as much patience (maybe even more) than teaching them C.

You're right, and it does take a lot of patience. Nevertheless, it also
takes patience on the part of those who are seeking help. I remember
getting a similarly rough ride from the regulars when I started using
clc, but it was so clear to me that they knew what they were talking
about that I put up with it, despite occasional rebuffs that I still
remember even now. For example, I once had a sig block in which I added
a new line for each new thing I'd learned in clc - until a regular
contributor pointed out that it was likely to become an extremely long
list! :) (The worrying thing is that he wasn't just being unkind - he
was also absolutely right!)
And I would hope that those that do not yet see eye to eye with the
regulars try to learn this lesson without being offended, if their
mistakes are pointed out with little empathy :)

Those who demonstrate that they really are trying to learn will normally
get pretty patient treatment here. But those who are looking for a
quick fix, a homework cheat or whatever, will find that the regulars
tend to undergo an empathectomy before responding.
 
B

Ben Bacarisse

<another version with undefined behaviour snipped>

Just because it has not (I think) been posted yet, I will say that it
is *possible*, that what the OP wanted was something like:

if (scanf("%d %c", &n, &c) == 2) {
/* do something with the input... *.
...
}
 
B

BiGYaN

Please trim quoted material when you post a followup. I particular,
don't quote singatures unless you're actually commenting on them.


(A very minor point; there's no "@" in my name.)



The fact that fflush(stdin) invokes undefined behavior has been
pounded to death, so I won't mention it again. (Oops, I just did!)
But on a system that does define the behavior, namely Solaris, the man
page says:

Flushing an input stream discards any buffered input and adjusts
the file pointer such that the next input operation accesses the
byte after the last one read.

For input from a keyboard, that means (I think) that it discards
anything in the typeahead buffer, i.e., any characters that the user
has typed that have not yet been read by input operations. You *don't
know* that the input buffer contains only a '\n' character; it could
contain anything.

fflush(stdin) is undefined; when it is defined, it doesn't necessarily
do what you think it does.

--
Keith Thompson (The_Other_Keith) (e-mail address removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"



I really did not know about this undefined behavior of "fflush(stdin)"
in C. Actually I had the same problem like this once and I solved it
using another dummy getchar() to consume the "\n". But then a friend
of mine showed me this function and I've been using it ever since. As
far I know it works in Windows, Solaris and Linux. I have no idea what
it does in other OSs as I simply don't have access to them.

As far as that getchar() and stdio.h is concerned, I just copy pasted
the code that was present in the starting post, so I didn't bother to
modify it. As far as I understood the problem the person had a problem
with that "\n" only. So I modified the code as little as possible. It
was just a quick and simple solution.
BTW, I am quite sure RH will surely quote this "quick and simple
solution". But let's wait for that.

As for that "@" it was supposed to mean "at". I see it being used
often in chat rooms to aim messages at a particular person and not the
group in general. So I just follwed it, not quite realizing that it
would be an alien protocol here.

As far that "not-so-learned" jab goes .... it's good to see multiple
interpretations of it. I never quite thought it could be interpreted
from 2 different angles. :)
I guess it is better to keep it open to interpretations, adding some
more fun to it.
 
B

BiGYaN

BiGYaN said:
BiGYaN said:
<snip>
How about this one :
int main()
{
char c;
int n;
scanf("%d",&n);
[snip]

I could never imagine writing a program in C without "#include
<stdio.h>". I just did not write it as I thought it was quite obvious
to add it at the start. But I'm sorry if it caused some inconvenience
to my not-so-learned friend.

You say could never imagine it, but how are we supposed to know that?
Plenty of programmers *don't* know that the "#include <stdio.h>" is
required, and omit it in real programs.

Ok, I didn't know that plenty of programmers don't know this. Actually
it was stressed so much in my C courses, that I really thought it was
quite obvious.
.... You may be a good enough
programmer that you never make that mistake yourself, but the only way
we can know that is if you demonstrate it. In this case, you
demonstrated the opposite.

I am just a Post Graduate CS student. I don't claim to be "good
enough". But I do agree that I was a bit callous in this case. I'll
surely keep your good advice in mind the next time I write a code.
You need to be just as careful with code you post here as with code
you write in the real world. The readers of this newsgroup tend to be
far more strict that most compilers, perhaps more so than any of them.

Yup I agree on the first point. The 2nd point is being proved in this
thread only. But I'll surely try to follow your advice.
"It will work fine in this case" is perhaps the greatest source of
errors, some of which may have drastic consequences. getchar()
returns an int. There is *never* a good reason to assign its result
to a char.

You might be right. Actually before taking that SW Engineering paper
on last year, I really never thought much of standards and
portability. Whatever compiled in both Windows and Linux was OK for
me. But I do have the realization now.
Code you post to comp.lang.c is unlikely to be cause any problems in
the real world; nobody is going to take a code snippet posted here and
use it to run a nuclear reactor. The worst consequence, as I hope
you're seeing now, is a bit of personal embarrassment. But this is an
opportunity to develop good habits that will serve you (and your
users) very well when you write code for the real world. Don't expect
us to ignore errors because they don't matter here; this is a learning
forum, and errors matter very much.

Well I am a student of CS. I am here to learn and maybe help others in
the process too. So I really don't mind. But I must confess, I never
thought that this small snippet of code could result in so many posts.
 
F

Flash Gordon

BiGYaN wrote, On 11/06/07 20:37:

I really did not know about this undefined behavior of "fflush(stdin)"
in C. Actually I had the same problem like this once and I solved it
using another dummy getchar() to consume the "\n". But then a friend
of mine showed me this function and I've been using it ever since. As
far I know it works in Windows, Solaris and Linux. I have no idea what
it does in other OSs as I simply don't have access to them.

You can't rely on the behaviour staying the same even on those systems
where it is documented. On the version of Linux I am running here, for
example, the documentation lists the stream not being open for output
(which stdin is not normally) as an error condition. It could just as
well have made the change without documenting the behaviour.

As far as that getchar() and stdio.h is concerned, I just copy pasted
the code that was present in the starting post, so I didn't bother to
modify it. As far as I understood the problem the person had a problem
with that "\n" only. So I modified the code as little as possible. It
was just a quick and simple solution.
BTW, I am quite sure RH will surely quote this "quick and simple
solution". But let's wait for that.

It is only a quick and simple solution if it is correct, anything that
is not correct does not IMHO count as a solution.
As for that "@" it was supposed to mean "at". I see it being used
often in chat rooms to aim messages at a particular person and not the
group in general. So I just follwed it, not quite realizing that it
would be an alien protocol here.

<snip>

Now you know that we don't do chatroom-speak here.
 
R

Richard Heathfield

BiGYaN said:

BTW, I am quite sure RH will surely quote this "quick and simple
solution".

How can I? I didn't /see/ a solution. All I saw was a series of
problems.
 
K

Keith Thompson

BiGYaN said:
BiGYaN said:
On Jun 10, 1:38 am, Keith Thompson <[email protected]> wrote:
[...]
Please trim quoted material when you post a followup. I particular,
don't quote singatures unless you're actually commenting on them.

Please read the above again; you're still failing to trim quoted
material.

[...]
I really did not know about this undefined behavior of "fflush(stdin)"
in C.

The comp.lang.c FAQ is at <http://www.c-faq.com/>. It's an excellent
source of information, and one that you should check before posting
here.

[...]
As far as that getchar() and stdio.h is concerned, I just copy pasted
the code that was present in the starting post, so I didn't bother to
modify it. As far as I understood the problem the person had a problem
with that "\n" only. So I modified the code as little as possible. It
was just a quick and simple solution.

Ok, that's a fair point. I've sometimes posted modified code that
corrects one error without noticing that there was another error.

But I don't then defend the error, as you did.
As for that "@" it was supposed to mean "at". I see it being used
often in chat rooms to aim messages at a particular person and not the
group in general. So I just follwed it, not quite realizing that it
would be an alien protocol here.

I've never seen that convention, but then I don't hang out in chat
rooms.
As far that "not-so-learned" jab goes .... it's good to see multiple
interpretations of it. I never quite thought it could be interpreted
from 2 different angles. :)
I guess it is better to keep it open to interpretations, adding some
more fun to it.

It came across as a deliberate insult directed at an individual. Even
if you didn't mean it that way, I see nothing "fun" about that. (Yes,
I did just post a long message advising someone else to grow a thicker
skin. I'm not always entirely consistent.)
 

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,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top