471,582 Members | 1,357 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,582 software developers and data experts.

scanf(), ungetc() behaviour.

I was curious at the start about how ungetc() returns the character to the
stream, so i did the following coding. Things work as expected except if I
change the scanf("%c",&j) to scanf("%d",&j). I don't understand how could
scanf() affect the content of i[0] and i[1]. Can someone tell me why?

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

void main()
{
char i[2], j;
printf("Please input a two digit number:");
i[0]= getchar();
i[1]= getchar();
ungetc(i[1],stdin);
ungetc(i[0],stdin);
scanf("%c", &j); //scanf("%d",&j);
fflush(stdin);
printf("\nYou entered %d in decimal and %c in character mode for
i[0]",i[0],i[0]);
printf("\nYou entered %d in decimal and %c in character mode for
i[1]",i[1],i[1]);
printf("\nYou entered %d in decimal and %c in character mode for j",j,j);

getchar();

}
Mar 3 '06 #1
62 4645
On Fri, 3 Mar 2006 10:19:19 +0800, "Argento" <ar********@hotmail.com>
wrote in comp.lang.c:
I was curious at the start about how ungetc() returns the character to the
stream, so i did the following coding. Things work as expected except if I
change the scanf("%c",&j) to scanf("%d",&j). I don't understand how could
scanf() affect the content of i[0] and i[1]. Can someone tell me why?
Your program has so many instances of undefined behavior that there is
nothing at all that the C standard has to say about what it should do.
#include <stdio.h>
#include <ctype.h>

void main()
The C standard requires that main() be defined with a return type of
int in a hosted environment, unless you have a C99 conforming compiler
that specifically documents that it accepts "void main()", and I will
most certainly bet that you do not. This means your program is
undefined.
{
char i[2], j;
printf("Please input a two digit number:");
i[0]= getchar();
i[1]= getchar();
ungetc(i[1],stdin);
ungetc(i[0],stdin);
You haven't checked the return value of the ungetc() function,
particularly the second one. Only one character of push back is
guaranteed by the standard. The second one could have failed.
scanf("%c", &j); //scanf("%d",&j);
'j' is a character and has a size of one byte (with 8 or more bits).
If you pass scanf() a "%d" conversion specifier and the address of
'j', you are telling scanf() to write an int into that one byte. On
your platform int has more than one byte, and so won't fit into 'j'
which only has room for a single character. You are lying to scanf()
when you use "%d" and this causes undefined behavior.
fflush(stdin);
The fflush() function is not defined for input streams, more undefined
behavior.
printf("\nYou entered %d in decimal and %c in character mode for
i[0]",i[0],i[0]);
printf("\nYou entered %d in decimal and %c in character mode for
i[1]",i[1],i[1]);
printf("\nYou entered %d in decimal and %c in character mode for j",j,j);

getchar();

}


Fix the undefined behavior in your program and then ask questions if
you are puzzled about what it does.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Mar 3 '06 #2
> The C standard requires that main() be defined with a return type of
int in a hosted environment, unless you have a C99 conforming compiler
that specifically documents that it accepts "void main()", and I will
most certainly bet that you do not. This means your program is
undefined.


Well, sorry. I don't know much about the standard but i am using DEV C++ and
the compiler compiles it happily.
I am just lazy with the 'return' when i don't check for it.

{
char i[2], j;
printf("Please input a two digit number:");
i[0]= getchar();
i[1]= getchar();
ungetc(i[1],stdin);
ungetc(i[0],stdin);


You haven't checked the return value of the ungetc() function,
particularly the second one. Only one character of push back is
guaranteed by the standard. The second one could have failed.


Ok, i checked on this after your post by replacing the two ungetc statement
with the following.
if( (ungetc(i[1],stdin))== i[1] ) printf("First ungetc() success.\n");
if( (ungetc(i[0],stdin))== i[0] ) printf("Second ungetc() success.\n");

It seems like that, i have no problem with pushing back both characters.
scanf("%c", &j); //scanf("%d",&j);


'j' is a character and has a size of one byte (with 8 or more bits).
If you pass scanf() a "%d" conversion specifier and the address of
'j', you are telling scanf() to write an int into that one byte. On
your platform int has more than one byte, and so won't fit into 'j'
which only has room for a single character. You are lying to scanf()
when you use "%d" and this causes undefined behavior.


You are right, I was careless. If I change j to 'int' things are solve,
however, it's still weird to change the content of i[0] and i[1].
Maybe scanf('%d", &j) when j is 'char' overwrite the memory of i[0]?
fflush(stdin);


The fflush() function is not defined for input streams, more undefined
behavior.


Well, i just keep on seeing examples that uses fflush( stdin ) and i was
told to do so after a scanf() and before a getchar()
because the '\n' is not taken by scanf("%d") or scanf("%c"). That was my
practice of clearing the stdin's buffer.
Any suggestion/alternative of doing so would be appreciated.

Mar 3 '06 #3
Argento wrote:
I was curious at the start about how ungetc() returns the character to the
stream, so i did the following coding. Things work as expected except if I
change the scanf("%c",&j) to scanf("%d",&j). I don't understand how could
scanf() affect the content of i[0] and i[1]. Can someone tell me why?

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

void main()

^^^^
Don't bother with trying to learn how ungetc() works until you stop this
absurd BullSchildtism.
Mar 3 '06 #4
Argento said:
The C standard requires that main() be defined with a return type of
int in a hosted environment, unless you have a C99 conforming compiler
that specifically documents that it accepts "void main()", and I will
most certainly bet that you do not. This means your program is
undefined.


Well, sorry. I don't know much about the standard but i am using DEV C++
and the compiler compiles it happily.


Nevertheless, it is incorrect. And now you *know* it's incorrect.

I know for certain that at least one regular contributor to this group, and
possibly more than one, has got into the habit of completely ignoring any
"plea-for-help" article in which the questioner has used void main, on the
grounds that they can't be all that serious about C if they can't even get
the entry point right.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Mar 3 '06 #5

"Martin Ambuhl" <ma*****@earthlink.net> wrote in message
news:bu*****************@newsread3.news.atl.earthl ink.net...
Argento wrote:
I was curious at the start about how ungetc() returns the character to
the stream, so i did the following coding. Things work as expected
except if I change the scanf("%c",&j) to scanf("%d",&j). I don't
understand how could scanf() affect the content of i[0] and i[1]. Can
someone tell me why?

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

void main()

^^^^
Don't bother with trying to learn how ungetc() works until you stop this
absurd BullSchildtism.


Ok, so i listened and search, then read about this
http://www.eskimo.com/~scs/readings/...in.960823.html
But i don't quite understand whether i should end my program with exit(0) or
return 0;
Can you explain to me pls?
Mar 3 '06 #6
Nevertheless, it is incorrect. And now you *know* it's incorrect.

I know for certain that at least one regular contributor to this group,
and
possibly more than one, has got into the habit of completely ignoring any
"plea-for-help" article in which the questioner has used void main, on the
grounds that they can't be all that serious about C if they can't even get
the entry point right.

I see. I didn't know it was that serious until i looked into the faq.
I was taught that way, "when you don't check for the return of main, why
declare int main?"
Now i know after reading
http://www.eskimo.com/~scs/readings/...in.960823.html
and i will change that habit :p
Mar 3 '06 #7
"Argento" <ar********@hotmail.com> writes:
[...]
Ok, so i listened and search, then read about this
http://www.eskimo.com/~scs/readings/...in.960823.html
But i don't quite understand whether i should end my program with exit(0) or
return 0;
Can you explain to me pls?


"exit(0);" and "return 0;" (within main) are almost exactly
equivalent. If you use exit, you must have a "#include <stdlib.h>" at
the top of your source file. The exit function can be used to
terminate the program from functions other than main; a return
statement from a function other than main just returns from that
function.

Use whichever one you like. (I usually use return, but it's no a big
deal.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <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.
Mar 3 '06 #8
Argento wrote:

<snip>
{
char i[2], j;
printf("Please input a two digit number:");
if you want your output to be guaranteed to appear put a
\n at the end or call fflush(stdout)

i[0]= getchar();
i[1]= getchar();
ungetc(i[1],stdin);
ungetc(i[0],stdin);
is there some sort of international shortage of whitespace
no one told me about? This is the third post in three days
which uses an atrocious layout. An indent of one!
You haven't checked the return value of the ungetc() function,
particularly the second one. Only one character of push back is
guaranteed by the standard. The second one could have failed.
Ok, i checked on this after your post by replacing the two ungetc statement
with the following.
if( (ungetc(i[1],stdin))== i[1] ) printf("First ungetc() success.\n");
if( (ungetc(i[0],stdin))== i[0] ) printf("Second ungetc() success.\n");

It seems like that, i have no problem with pushing back both characters.


it's not portable though

<snip>

fflush(stdin);


The fflush() function is not defined for input streams, more undefined
behavior.


Well, i just keep on seeing examples that uses fflush( stdin )


they are wrong. If your book uses void main() and fflush(stdout) then
destroy it. DO NOT give it to a charity shop as some other poor sucker
will mistake it for a C book. If you want a good book try
http://cm.bell-labs.com/cm/cs/cbook/
and i was
told to do so after a scanf() and before a getchar()
because the '\n' is not taken by scanf("%d") or scanf("%c"). That was my
practice of clearing the stdin's buffer.
Any suggestion/alternative of doing so would be appreciated.


don't use scanf() use fgets() followed by sscanf()
--
Nick Keighley

"Half-assed programming was a time-filler that, like knitting,
must date to the beginning of human experience."
"A Fire Upon The Deep" by Verne Vinge

Mar 3 '06 #9
"exit(0);" and "return 0;" (within main) are almost exactly
equivalent. If you use exit, you must have a "#include <stdlib.h>" at
the top of your source file. The exit function can be used to
terminate the program from functions other than main; a return
statement from a function other than main just returns from that
function.

Use whichever one you like. (I usually use return, but it's no a big
deal.)


Thx, that's what i got too from K&R2 Sec. 7.6 pp.164. Except that it says
exit has the advantage call from other function and that exit calls flcose
for each
open output file to flush out any buffered output.

Yet, a friend of mine told me not to rely on it and do the flcose() myself.
Mar 3 '06 #10
> if you want your output to be guaranteed to appear put a
\n at the end or call fflush(stdout)
Thx for the clue.

>> i[0]= getchar();
>> i[1]= getchar();
>> ungetc(i[1],stdin);
>> ungetc(i[0],stdin);
is there some sort of international shortage of whitespace
no one told me about? This is the third post in three days
which uses an atrocious layout. An indent of one!
English is not my native language, i don't quite understand what you
mean.
Are you saying that my coding habit is lack of whitespace? If it is, well, i
was
just trying to test how ungetc works , so it's like draft work...sorry.
> You haven't checked the return value of the ungetc() function,
> particularly the second one. Only one character of push back is
> guaranteed by the standard. The second one could have failed.


Ok, i checked on this after your post by replacing the two ungetc
statement
with the following.
if( (ungetc(i[1],stdin))== i[1] ) printf("First ungetc() success.\n");
if( (ungetc(i[0],stdin))== i[0] ) printf("Second ungetc() success.\n");

It seems like that, i have no problem with pushing back both characters.


it's not portable though


Not portable? Why not?
<snip>

>> fflush(stdin);
>
> The fflush() function is not defined for input streams, more undefined
> behavior.
Well, i just keep on seeing examples that uses fflush( stdin )


they are wrong. If your book uses void main() and fflush(stdout) then
destroy it. DO NOT give it to a charity shop as some other poor sucker
will mistake it for a C book. If you want a good book try
http://cm.bell-labs.com/cm/cs/cbook/


No, no , no. My book doesn't use void main() it was my lazy habit (which i
will change from now onwards)
It was fflush( stdin ) that i use, not fflush( stdout ) :p
As a matter of fact, i do have K&R's book but i only made it to page 38.
and i was
told to do so after a scanf() and before a getchar()
because the '\n' is not taken by scanf("%d") or scanf("%c"). That was my
practice of clearing the stdin's buffer.
Any suggestion/alternative of doing so would be appreciated.


don't use scanf() use fgets() followed by sscanf()


I do know about this, what i meant was alternative to fflush( stdin ). I am
a beginner who doesn't
have much experience with stream, I/O and memory, so i always run away from
using fgets()
and sscanf() in cases like this one (just to test a function). I will put
more hard work on learning
how to use these functions so that i won't make the same mistakes again.
Thank you.
Mar 3 '06 #11
>> >> fflush(stdin);
>
> The fflush() function is not defined for input streams, more undefined
> behavior.


Well, i just keep on seeing examples that uses fflush( stdin )


they are wrong. If your book uses void main() and fflush(stdout) then
destroy it. DO NOT give it to a charity shop as some other poor sucker
will mistake it for a C book. If you want a good book try
http://cm.bell-labs.com/cm/cs/cbook/
and i was
told to do so after a scanf() and before a getchar()
because the '\n' is not taken by scanf("%d") or scanf("%c"). That was my
practice of clearing the stdin's buffer.
Any suggestion/alternative of doing so would be appreciated.


don't use scanf() use fgets() followed by sscanf()


Ah, i read about this about a week ago.
http://c-faq.com/stdio/gets_flush2.html

while((c = getchar()) != '\n' && c != EOF)
/* discard the character */;

FYI, unfortunately, when i check back on my university's course unit just
now. They do use
void main() and fflush( stdin ) :(
Mar 3 '06 #12
On 2006-03-03, Argento <ar********@hotmail.com> wrote:
Use whichever one you like. (I usually use return, but it's no a big
deal.)
Thx, that's what i got too from K&R2 Sec. 7.6 pp.164. Except that it says
exit has the advantage call from other function and that exit calls flcose
for each
open output file to flush out any buffered output.


No, both a return from main, and a call to exit results in closing all
the open files and flushing the repsective buffers. They are identical
in this respect.
Yet, a friend of mine told me not to rely on it and do the flcose() myself.


That's what I do, but not out of fear that returning from main will let
them open. It's a matter of style, it simply looks better, more
symmetric if you will, to explicitly close what you open.

--
John Tsiombikas (Nuclear / Mindlapse)
nu*****@siggraph.org
http://nuclear.demoscene.gr/
Mar 3 '06 #13
On 2006-03-03, Argento <ar********@hotmail.com> wrote:
is there some sort of international shortage of whitespace no one
told me about? This is the third post in three days which uses an
atrocious layout. An indent of one!


English is not my native language, i don't quite understand what you
mean. Are you saying that my coding habit is lack of whitespace? If
it is, well, i was just trying to test how ungetc works , so it's like
draft work...sorry.


I've heard this excuse a lot, "it's just a test program, no need to
indent properly", "I'm not going to show it to anyone", etc.
However, fact is that in order to be able to build a good programming
style, which you follow automatically and write readable code even in
your sleep, you *have* to use proper indentation and consistent style
even in 5-line tests. That way, writting readably becomes a habbit and
you don't even have to think about it anymore.
if( (ungetc(i[1],stdin))== i[1] ) printf("First ungetc() success.\n");
if( (ungetc(i[0],stdin))== i[0] ) printf("Second ungetc() success.\n");

It seems like that, i have no problem with pushing back both characters.


it's not portable though


Not portable? Why not?


Because the C standard says: "One character of pushback is guaranteed.
If the ungetc function is called too many times on the same stream
without an intervening read or file positioning operation on that
stream, the operation may fail."

--
John Tsiombikas (Nuclear / Mindlapse)
nu*****@siggraph.org
http://nuclear.demoscene.gr/
Mar 3 '06 #14
On Fri, 3 Mar 2006 16:16:09 +0800, in comp.lang.c , "Argento"
<ar********@hotmail.com> wrote:
It seems like that, i have no problem with pushing back both characters.


it's not portable though


Not portable? Why not?


Because the C standard doesn't require it. Therefore if you tried this
again on ac different version of linux, or on windows, or on VMS, it
might not work. Its very dangerous to rely on undefined behaviour,
which just happens to work ok on your particular platform, unless you
understand *precisely* why it works.
Well, i just keep on seeing examples that uses fflush( stdin )


they are wrong.
Any suggestion/alternative of doing so would be appreciated.


This is actually a FAQ - search for fflush.

Mark McIntyre
--
CLC FAQ <http://c-faq.com/>
CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt>

----== Posted via Newsfeeds.Com - Unlimited-Unrestricted-Secure Usenet News==----
http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
----= East and West-Coast Server Farms - Total Privacy via Encryption =----
Mar 3 '06 #15
On Fri, 3 Mar 2006 16:28:12 +0800, in comp.lang.c , "Argento"
<ar********@hotmail.com> wrote:
FYI, unfortunately, when i check back on my university's course unit just
now. They do use
void main() and fflush( stdin ) :(


Yes, its very annoying when that happens. All one can do is ignore it,
and learn the correct way.
Mark McIntyre
--
"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan

----== Posted via Newsfeeds.Com - Unlimited-Unrestricted-Secure Usenet News==----
http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
----= East and West-Coast Server Farms - Total Privacy via Encryption =----
Mar 3 '06 #16
"Argento" <ar********@hotmail.com> writes:
"exit(0);" and "return 0;" (within main) are almost exactly
equivalent. If you use exit, you must have a "#include <stdlib.h>" at
the top of your source file. The exit function can be used to
terminate the program from functions other than main; a return
statement from a function other than main just returns from that
function.

Use whichever one you like. (I usually use return, but it's no a big
deal.)
Thx, that's what i got too from K&R2 Sec. 7.6 pp.164. Except that it
says exit has the advantage call from other function and that exit
calls flcose for each open output file to flush out any buffered
output.


Yes, exit has the advantage that you can call it from anywhere, but
all open files will be closed whether you use exit or return. (The
only difference is an extremely subtle one involving accessing objects
local to main from a function registered with atexit(); you'll almost
certainly never run into anything like that.)
Yet, a friend of mine told me not to rely on it and do the flcose()
myself.


Yes, that's a good idea -- not because the implementation might not
close the files (it's required to by the standard), but because it's
just good practice. Your main program could some day become part of a
larger program, for example. It's (almost) always a good idea to
clean up after yourself.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <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.
Mar 3 '06 #17

"Argento" <ar********@hotmail.com> writes:
Nevertheless, it is incorrect. And now you *know* it's incorrect.

I know for certain that at least one regular contributor to this group,
and
possibly more than one, has got into the habit of completely ignoring any
"plea-for-help" article in which the questioner has used void main, on the
grounds that they can't be all that serious about C if they can't even get
the entry point right.

I see. I didn't know it was that serious until i looked into the faq.
I was taught that way, "when you don't check for the return of main, why
declare int main?"


When you don't check for the return of main, why spend one more
letter declaring it ("void" instead of "int")?
(Not that this would be any sort of working argument if "int" was spelled
"integer"...)

Mar 3 '06 #18

"Argento" <ar********@hotmail.com> writes:
"Martin Ambuhl" <ma*****@earthlink.net> wrote in message
news:bu*****************@newsread3.news.atl.earthl ink.net...
Argento wrote:
I was curious at the start about how ungetc() returns the character to
the stream, so i did the following coding. Things work as expected
except if I change the scanf("%c",&j) to scanf("%d",&j). I don't
understand how could scanf() affect the content of i[0] and i[1]. Can
someone tell me why?

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

void main()

^^^^
Don't bother with trying to learn how ungetc() works until you stop this
absurd BullSchildtism.


Ok, so i listened and search, then read about this
http://www.eskimo.com/~scs/readings/...in.960823.html
But i don't quite understand whether i should end my program with exit(0) or
return 0;
Can you explain to me pls?


I prefer using 'return' from main, for about the only reason that I
may otherwise get compilation warnings telling me that the code
between the call to 'exit' and the end of the function is not reached.

There is a preprocessor symbol defined by the standard for indicating
successful exit: EXIT_SUCCESS (and one for failure - EXIT_FAILURE). It
is usually 0, but I suppose it must be something else in some environment.
Mar 3 '06 #19
Argento wrote:

'j' is a character and has a size of one byte (with 8 or more bits).
If you pass scanf() a "%d" conversion specifier and the address of
'j', you are telling scanf() to write an int into that one byte. On
your platform int has more than one byte, and so won't fit into 'j'
which only has room for a single character. You are lying to
scanf() when you use "%d" and this causes undefined behavior.


You are right, I was careless. If I change j to 'int' things are
solve, however, it's still weird to change the content of i[0] and
i[1]. Maybe scanf('%d", &j) when j is 'char' overwrite the memory of
i[0]?

It's not weird at all. As Jack told you, it's trying to write more data
than will fit into a char. So where does the extra data go? In your
case, it writes into some other automatic data "adjacent" to the char
variable j. This is one form of undefined behavior, silently changing
some other variables. If you're lucky, the program crashes when you do
something like that. You didn't get that lucky.

Brian
--
Please quote enough of the previous message for context. To do so from
Google, click "show options" and use the Reply shown in the expanded
header.
Mar 3 '06 #20
Arndt Jonasson <do********@invalid.net> writes:
[...]
I prefer using 'return' from main, for about the only reason that I
may otherwise get compilation warnings telling me that the code
between the call to 'exit' and the end of the function is not reached.
Why would you have code between a call to exit and the end of the
function?
There is a preprocessor symbol defined by the standard for indicating
successful exit: EXIT_SUCCESS (and one for failure - EXIT_FAILURE). It
is usually 0, but I suppose it must be something else in some environment.


And of course 0 is also a valid and portable exit status.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <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.
Mar 3 '06 #21
In article <ln************@nuthaus.mib.org>,
Keith Thompson <ks***@mib.org> wrote:
Arndt Jonasson <do********@invalid.net> writes:
I prefer using 'return' from main, for about the only reason that I
may otherwise get compilation warnings telling me that the code
between the call to 'exit' and the end of the function is not reached.

Why would you have code between a call to exit and the end of the
function?


I have observed compilers sometimes complain that the implicit return
of a function was not reachable when the function ended with exit()...
even in some very straight forward cases.

I haven't observed it particularily recently; it's a QOI issue that
has probably generally improved over time.
--
Programming is what happens while you're busy making other plans.
Mar 3 '06 #22
Richard Heathfield wrote:
Argento said:

.... snip ...

Well, sorry. I don't know much about the standard but i am using
DEV C++ and the compiler compiles it happily.


Nevertheless, it is incorrect. And now you *know* it's incorrect.

I know for certain that at least one regular contributor to this
group, and possibly more than one, has got into the habit of
completely ignoring any "plea-for-help" article in which the
questioner has used void main, on the grounds that they can't be
all that serious about C if they can't even get the entry point
right.


Well, I have taken to cutting things back to the first few glaring
errors, such as #include <conio.h> or void main(), and ignoring the
rest (assuming I decide to answer at all). After all, one needs to
fix the earliest errors first, all else may well be spurious. This
also reduces the bandwidth wastage.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
Also see <http://www.safalra.com/special/googlegroupsreply/>
Mar 3 '06 #23
Nick Keighley wrote:
Argento wrote:

.... snip ...

Well, i just keep on seeing examples that uses fflush( stdin )


they are wrong. If your book uses void main() and fflush(stdout) then
destroy it. DO NOT give it to a charity shop as some other poor sucker
will mistake it for a C book. If you want a good book try
http://cm.bell-labs.com/cm/cs/cbook/


Harrumph. Book burning for fflush(stdout) would be unwise, not to
mention profligate. :-)

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
Also see <http://www.safalra.com/special/googlegroupsreply/>
Mar 3 '06 #24
Argento wrote:
.... snip ...
I do know about this, what i meant was alternative to fflush(stdin).
I am a beginner who doesn't have much experience with stream, I/O
and memory, so i always run away from using fgets() and sscanf() in
cases like this one (just to test a function). I will put more hard
work on learning how to use these functions so that i won't make
the same mistakes again.


Consider the following function:

int flushln(FILE *f) {
int ch;

do {
ch = getc(f);
while (('\n' != ch) && (EOF != ch));
return ch;
}

Each call will eat up the remainder of a line. If the previous
line has already been eaten it will eat the next line, so you need
to keep track of when you absorb '\n's.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
Also see <http://www.safalra.com/special/googlegroupsreply/>
Mar 3 '06 #25
Argento wrote:
.... snip about usage of ungetc ...

it's not portable though


Not portable? Why not?


Please don't snip attributions for material you quote. Please DO
snip material not germane to your reply, and attributions for
material totally snipped.
From N869:


7.19.5.2 The fflush function

Synopsis

[#1]
#include <stdio.h>
int fflush(FILE *stream);

Description

[#2] If stream points to an output stream or an update
stream in which the most recent operation was not input, the
fflush function causes any unwritten data for that stream to
be delivered to the host environment to be written to the
file; otherwise, the behavior is undefined.

[#3] If stream is a null pointer, the fflush function
performs this flushing action on all streams for which the
behavior is defined above.

Returns

[#4] The fflush function sets the error indicator for the
stream and returns EOF if a write error occurs, otherwise it
returns zero.

After ungetc has been called, the most recent operation on the
stream most definitely was not input. This allows a strict limit
on the buffer space that must be provided.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
Also see <http://www.safalra.com/special/googlegroupsreply/>
Mar 3 '06 #26
Argento wrote:
.... snip ...
FYI, unfortunately, when i check back on my university's course
unit just now. They do use
void main() and fflush( stdin ) :(


Publish the instructors email address here and we will collectively
set him/her right. It is not right to warp the minds of the
innocent.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
Also see <http://www.safalra.com/special/googlegroupsreply/>
Mar 3 '06 #27
"John Tsiombikas (Nuclear / Mindlapse)" wrote:

On 2006-03-03, Argento <ar********@hotmail.com> wrote:
.... snip ...
No, both a return from main, and a call to exit results in closing
all the open files and flushing the repsective buffers. They are
identical in this respect.
Yet, a friend of mine told me not to rely on it and do the
flcose() myself.


That's what I do, but not out of fear that returning from main
will let them open. It's a matter of style, it simply looks
better, more symmetric if you will, to explicitly close what you
open.


The reason for doing it yourself is that you get to test for
closing errors, and then you can decide what, if any, remedial
steps to take. This may be crucial in avoiding data loss.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
Also see <http://www.safalra.com/special/googlegroupsreply/>

Mar 3 '06 #28
Nick Keighley said:
If your book uses void main() and fflush(stdout) then
destroy it.


(You mean fflush(stdin), of course.) Before deciding whether to burn the
book, however, please ensure that it is not merely using them as examples
of common errors to be avoided.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Mar 3 '06 #29
Walter Roberson wrote:
.... snip ...
I have observed compilers sometimes complain that the implicit
return of a function was not reachable when the function ended
with exit()... even in some very straight forward cases.


Good for them. I consider that a sign of poor code structure.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
Also see <http://www.safalra.com/special/googlegroupsreply/>
Mar 4 '06 #30
Well, I have taken to cutting things back to the first few glaring
errors, such as #include <conio.h> or void main(), and ignoring the
rest (assuming I decide to answer at all). After all, one needs to
fix the earliest errors first, all else may well be spurious. This
also reduces the bandwidth wastage.


After so a few replies to me, i have understand about the problem with
void main() but i do not have much idea about <conio.h> other then its
not in the standard. Is there any other problem related to it other then its
not in the stardard/less portable?
Mar 4 '06 #31
Publish the instructors email address here and we will collectively
set him/her right. It is not right to warp the minds of the
innocent.


Are you serious about this? Before you answer that first question, I
would just want you to know, those course books are from OUHK
(Open University of Hong Kong, that's where I currently study about this)
taken from the course code MT258.
Mar 4 '06 #32
(You mean fflush(stdin), of course.) Before deciding whether to burn the
book, however, please ensure that it is not merely using them as examples
of common errors to be avoided.

Definitely not. It's used in almost every-little-single code, lol.
Mar 4 '06 #33
The reason for doing it yourself is that you get to test for
closing errors, and then you can decide what, if any, remedial
steps to take. This may be crucial in avoiding data loss.

Yes, yes, error checking *-)
Because I am just at Unit 5 of the course, there ain't much error
checking idea in my mind yet. Thanks, very informative.
Mar 4 '06 #34
Argento wrote:
Well, I have taken to cutting things back to the first few glaring
errors, such as #include <conio.h> or void main(), and ignoring the
rest (assuming I decide to answer at all). After all, one needs to
fix the earliest errors first, all else may well be spurious. This
also reduces the bandwidth wastage.


After so a few replies to me, i have understand about the problem with
void main() but i do not have much idea about <conio.h> other then its
not in the standard. Is there any other problem related to it other
then its not in the stardard/less portable?


Please do not remove attribution lines when quoting. It's imporatnat to
know who said what, as well.

As for conio.h, there's nothing wrong with it as such (AFAIK). It's just
that it's implementation and system specific and thus off topic here.
If you have questions about it, they're better answered in one of the
Borland or MS-DOS groups (if my memory serves, but look it up
yourself).

The only possible thing "wrong" with conio.h is that as soon as it's in
your program, it (your program) becomes non-portable, which in these
parts is considered a Bad Thing.

--
BR, Vladimir

We are experiencing system trouble -- do not adjust your terminal.

Mar 4 '06 #35
Argento wrote:
The reason for doing it yourself is that you get to test for
closing errors, and then you can decide what, if any, remedial
steps to take. This may be crucial in avoiding data loss.

Yes, yes, error checking *-)
Because I am just at Unit 5 of the course, there ain't much error
checking idea in my mind yet. Thanks, very informative.


You're around 4 units late in starting error checking... ;-)

(don't snip attributions)

--
BR, Vladimir

Loose bits sink chips.

Mar 4 '06 #36
Argento wrote:
Publish the instructors email address here and we will collectively
set him/her right. It is not right to warp the minds of the
innocent.


Are you serious about this? Before you answer that first question, I
would just want you to know, those course books are from OUHK
(Open University of Hong Kong, that's where I currently study about
this) taken from the course code MT258.


In my experience, collective mind of c.l.c regulars trumps your (or any)
University or course books.

(attributions please)

--
BR, Vladimir

At a contest for farting in Butte
One lady's exertion was cute :
It won the diploma
For fetid aroma,
And three judges were felled by the brute.

Mar 4 '06 #37
Argento wrote:
(You mean fflush(stdin), of course.) Before deciding whether to burn
the book, however, please ensure that it is not merely using them as
examples of common errors to be avoided.

Definitely not. It's used in almost every-little-single code, lol.


Can I watch them burn? ;-)

--
BR, Vladimir

Very few profundities can be expressed in less than 80 characters.

Mar 4 '06 #38

"Vladimir S. Oka" <no****@btopenworld.com> wrote in message
news:du**********@nwrdmz01.dmz.ncs.ea.ibs-infra.bt.com...
Please do not remove attribution lines when quoting. It's imporatnat to
know who said what, as well.

As for conio.h, there's nothing wrong with it as such (AFAIK). It's just
that it's implementation and system specific and thus off topic here.
If you have questions about it, they're better answered in one of the
Borland or MS-DOS groups (if my memory serves, but look it up
yourself).

The only possible thing "wrong" with conio.h is that as soon as it's in
your program, it (your program) becomes non-portable, which in these
parts is considered a Bad Thing.


Thanks. I had been reading this newsgroup like a month and only starting
from
yesterday, do i post. Sorry for removing the attribution lines and snip
thing, I use
to roam about in the local newsgroups (Hong Kong, that's where I live), they
have
different manners. They do top-posting and quote the whole thing. I guess I
got
lots to learn from all of you other then C questions.
Mar 4 '06 #39
Argento wrote:

"Vladimir S. Oka" <no****@btopenworld.com> wrote in message
news:du**********@nwrdmz01.dmz.ncs.ea.ibs-infra.bt.com...
Please do not remove attribution lines when quoting. It's imporatnat
to know who said what, as well.

As for conio.h, there's nothing wrong with it as such (AFAIK). It's
just that it's implementation and system specific and thus off topic
here. If you have questions about it, they're better answered in one
of the Borland or MS-DOS groups (if my memory serves, but look it up
yourself).

The only possible thing "wrong" with conio.h is that as soon as it's
in your program, it (your program) becomes non-portable, which in
these parts is considered a Bad Thing.


Thanks. I had been reading this newsgroup like a month and only
starting from
yesterday, do i post. Sorry for removing the attribution lines and
snip thing, I use
to roam about in the local newsgroups (Hong Kong, that's where I
live), they have
different manners. They do top-posting and quote the whole thing. I
guess I got
lots to learn from all of you other then C questions.


Every group has it's own customs. In brief, here you don't top-post,
don't remove attributions, and try to snip stuff that's not relevant,
while leaving enough context. The last one may be difficult, so not
doing it is normally not commented upon (unless you quote a whole 100+
line post with little benefit). Also, your replies should be
interspersed with the quoted text if it makes it clearer to what part
of the post you're replying to. There are also rules on topicality, but
these are better learned by lurking.

Anyway, thanks for taking an interest in learning local customs.

PS
Asbestos underware may also come in handy. ;-)

--
BR, Vladimir

I read Playboy for the same reason I read National Geographic.
To see the sights I'm never going to visit.

Mar 4 '06 #40
On Sat, 04 Mar 2006 17:33:10 +0800, Argento wrote:
Publish the instructors email address here and we will collectively set
him/her right. It is not right to warp the minds of the innocent.


Are you serious about this? Before you answer that first question, I would
just want you to know, those course books are from OUHK (Open University
of Hong Kong, that's where I currently study about this) taken from the
course code MT258.


I would not push this too far if I were you. I have had a look at some
of the TMA solutions and there are worse errors in there the void main()
and fflush(stdin)! One solution has some very odd logic (I can't say
"wrong" because the spec. is not given in the solution paper so it is
possible the strange behaviour is allowed). In one place in the
supporting material by the same author gets and scanf("%[\n]", ...) are
given as examples. In another, the example can overwrite an array.
Others use sentinel values which I don't think of a good practise.

Even good book can have errors, but these just look like bad teaching
examples to me.

--
Ben.
Mar 5 '06 #41
Argento wrote:
Publish the instructors email address here and we will collectively
set him/her right. It is not right to warp the minds of the
innocent.


Are you serious about this? Before you answer that first question, I
would just want you to know, those course books are from OUHK
(Open University of Hong Kong, that's where I currently study about
this) taken from the course code MT258.


Yes, I am serious. I don't know what we want to set him right
about, since you snipped that portion. However I vaguely remember
writing the above, although you snipped the attributions. Please
don't do that. I guess snipping is an acquired art.

We all have an interest in not having bad teachers go uncorrected.
They produce bad product, and make life harder for all of us
correcting those ex-students. Some of us will be more diplomatic
than others, and some will be outright rude.

I suspect if you, as a student, go to your instructor and insist
that he cease and desist from misinformation, it will adversely
affect your marks. However if peers tell him the same, usually
with bell, book, candle, and standards references in hand, s/he may
listen and no evil retribution will fall on you.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
Also see <http://www.safalra.com/special/googlegroupsreply/>
Mar 5 '06 #42
CBFalconer wrote:
Argento wrote:
Publish the instructors email address here and we will collectively
set him/her right. It is not right to warp the minds of the
innocent.


Are you serious about this? Before you answer that first question, I
would just want you to know, those course books are from OUHK
(Open University of Hong Kong, that's where I currently study about
this) taken from the course code MT258.

Yes, I am serious. I don't know what we want to set him right
about, since you snipped that portion. However I vaguely remember
writing the above, although you snipped the attributions. Please
don't do that. I guess snipping is an acquired art.

We all have an interest in not having bad teachers go uncorrected.
They produce bad product, and make life harder for all of us
correcting those ex-students. Some of us will be more diplomatic
than others, and some will be outright rude.

I suspect if you, as a student, go to your instructor and insist
that he cease and desist from misinformation, it will adversely
affect your marks. However if peers tell him the same, usually
with bell, book, candle, and standards references in hand, s/he may
listen and no evil retribution will fall on you.

In my own experience, the young student who demands the instructor cease
and desist from anything at all, will lose big time. If student finds
instructor incompetent, student should change instructors. No student
has ever won the fight with the instructor, in my experience.

--
Joe Wright
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
Mar 5 '06 #43
Richard Heathfield wrote:
Argento said:

The C standard requires that main() be defined with a return type of
int in a hosted environment, unless you have a C99 conforming compiler
that specifically documents that it accepts "void main()", and I will
most certainly bet that you do not. This means your program is
undefined.


Well, sorry. I don't know much about the standard but i am using DEV C++
and the compiler compiles it happily.

Nevertheless, it is incorrect. And now you *know* it's incorrect.

I know for certain that at least one regular contributor to this group, and
possibly more than one, has got into the habit of completely ignoring any
"plea-for-help" article in which the questioner has used void main, on the
grounds that they can't be all that serious about C if they can't even get
the entry point right.


Is "void main" really that bad?

Does anyone have any statistics on the compilers that "void main" causes
problems with?

I suspect that such statistics would show that the use of "void main"
has similar ramifications to tearing off the tag of a bed mattress. If
anyone can prove me wrong, please back it up with some numbers.

--
jaysome
Mar 5 '06 #44
jaysome wrote:
Richard Heathfield wrote:
Argento said:

The C standard requires that main() be defined with a return type of
int in a hosted environment, unless you have a C99 conforming
compiler that specifically documents that it accepts "void main()",
and I will
most certainly bet that you do not. This means your program is
undefined.

Well, sorry. I don't know much about the standard but i am using DEV
C++ and the compiler compiles it happily.

Nevertheless, it is incorrect. And now you *know* it's incorrect.

I know for certain that at least one regular contributor to this
group, and possibly more than one, has got into the habit of
completely ignoring any "plea-for-help" article in which the
questioner has used void main, on the grounds that they can't be all
that serious about C if they can't even get the entry point right.


Is "void main" really that bad?

Does anyone have any statistics on the compilers that "void main"
causes problems with?

I suspect that such statistics would show that the use of "void main"
has similar ramifications to tearing off the tag of a bed mattress. If
anyone can prove me wrong, please back it up with some numbers.


I don't think `void main()` will really do any nasty things to you.
However, most examples come from posters who are obviously new and
inexperienced, and I believe it signifies either bad teaching they've
been exposed to or not really caring about learning proper C. Something
along the lines of not capitalising `i`s and sentences, and using `u`,
`ur` and similar contractions.

Ask any of them about whether their particular implementation actually
allows `void main()`, which it can if it documents it, they wouldn't
have a clue what you're talking about. And of course, even if it did,
it wouldn't be portable, Standard C, and so would be off-topic here.

--
BR, Vladimir

Cleanliness becomes more important when godliness is unlikely.
-- P.J. O'Rourke

Mar 5 '06 #45
jaysome <ja*****@spamcop.com> writes:
Richard Heathfield wrote:
Argento said:
The C standard requires that main() be defined with a return type of
int in a hosted environment, unless you have a C99 conforming compiler
that specifically documents that it accepts "void main()", and I will
most certainly bet that you do not. This means your program is
undefined.

Well, sorry. I don't know much about the standard but i am using DEV C++
and the compiler compiles it happily. Nevertheless, it is incorrect. And now you *know* it's incorrect.
I know for certain that at least one regular contributor to this
group, and possibly more than one, has got into the habit of
completely ignoring any "plea-for-help" article in which the
questioner has used void main, on the grounds that they can't be all
that serious about C if they can't even get the entry point right.


Is "void main" really that bad?


Yes.
Does anyone have any statistics on the compilers that "void main"
causes problems with?
I don't know, but that's not really the point.
I suspect that such statistics would show that the use of "void main"
has similar ramifications to tearing off the tag of a bed mattress. If
anyone can prove me wrong, please back it up with some numbers.


There is quite simply no reason to use "void main". Unless you happen
to be using an implementation that (unwisely, IMHO) documents the use
of "void main" as an extension, using it invokes undefined behavior.
Most likely it will work as expected; the worst *likely* problem is
that the program will return an unpredictable exit status to the
environment (which is a good enough reason in itself to avoid it).
But it also means that any time your program doesn't behave as you
expected, you can't be certain that your use of "void main" didn't
cause the problem.

Consistently using the *correct* form costs nothing, and it means you
always have one less thing to worry about.

"void main" *probably* won't cause any real problems, but unless
you're using random numbers, programming isn't about probabilities.
It's about writing correct code that does what you want it to do.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <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.
Mar 5 '06 #46
jaysome said:
Richard Heathfield wrote:

...they can't be all that serious about C if they can't
even get the entry point right.
Is "void main" really that bad?


Yes, for the reason I gave above.

It's called "cargo cult" programming. Setting aside freestanding
implementations for a moment, there is never a good reason to use void
main. So where does it come from? Not from thinking, that's for sure. No,
people use it because they've seen other people using it, without thinking
of the possibility that those they emulate may not be all that great at C
themselves. Computers copy stuff blindly about the place without
understanding it. People are supposed to be brighter than that.
Does anyone have any statistics on the compilers that "void main" causes
problems with?
Does anyone have statistics on the number of programs that have failed
because of undefined behaviour?
I suspect that such statistics would show that the use of "void main"
has similar ramifications to tearing off the tag of a bed mattress. If
anyone can prove me wrong, please back it up with some numbers.


I suspect that statistics would show that those who don't care enough about
correctness to get the entry point right are also likely not to care enough
about getting other things right. So why bother trying to teach them? Just
let them guess and hope.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Mar 5 '06 #47
On 2006-03-05, Richard Heathfield <in*****@invalid.invalid> wrote:
jaysome said:
Richard Heathfield wrote:

...they can't be all that serious about C if they can't
even get the entry point right.


Is "void main" really that bad?


Yes, for the reason I gave above.

It's called "cargo cult" programming. Setting aside freestanding
implementations for a moment, there is never a good reason to use void
main.


My entire career is freestanding implementations or things like vxWorks
where you just don't use main() at all.

Why?

Requirments for those types of things often state "ANSI (or ISO) C, with
no extensions," "No warnings from the compiler set at its most stringent
level," and "No unreachable code"

Defining main() void or with the wrong parameters violates the first
requirement (non-ANSI).

Ignoring the warning from main() not returning violates the Second
requirement (causes warnings).

Sticking a return; after a never exits loop violates the third
(unreachable code).

While there exist freestanding, as well as hosted, implementations where
it works, there's rather an enormous gulf between:

"This works on this version of the compiler running under this
processor on this OS cross-compiling to that processor under that OS"

and:

"This is Standard and supported by any conforming implementation."
Mar 5 '06 #48
On Sun, 05 Mar 2006 02:07:41 -0500, Joe Wright wrote:
No student has
ever won the fight with the instructor, in my experience.


That may be true, but there should be no fight in the first place. Good
instructors know they can make mistakes and learn from them (rather more
students think they know better that actually do, but that should be no
excuse). To swing back almost OT, I once presented something rather like
this:

int order2(int *a, int *b)
{
if (*a > *b) {
int tmp = *a; *a = *b; *b = tmp;
return 1;
}
return 0;
}

int order4(int *a, int *b, int *c, int *d)
{
int swaps = 0;
while (order2(a, b) || order2(b, c) || order2(c, d))
swaps++;
return swaps;
}

and asked for an informal argument about the termination of the loop in
order4. It was not actually C, but no matter. Most were doing what I
wanted (informally showing that the loop terminates) and getting good
grades for that part until someone pointed out what will happen with
aliased pointers. Obvious enough, maybe, but I was thinking about other
matters when writing the assignment. The next year, the question was
better and asked for two arguments -- including one for when the pointers
might be aliased!

I would be wary of any teacher who does not learn from their students.

--
Ben.
Mar 5 '06 #49
In article <l8******************************@comcast.com>,
Charles Krug <cd****@aol.com> wrote:
My entire career is freestanding implementations or things like vxWorks
where you just don't use main() at all.


Of course, if you do not use a main() at all, there is no need to
concern yourself with the return-type and parameter(s) to main(). :-)

I actually prefer avoiding main() entirely in freestanding code,
for this reason.

(Also: although it is off topic, I will mention that as of 6.x, vxWorks
does use "main" functions in RTPs.)
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Mar 5 '06 #50

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

21 posts views Thread by clusardi2k | last post: by
20 posts views Thread by Sivarn | last post: by
6 posts views Thread by Rob Thorpe | last post: by
33 posts views Thread by Lalatendu Das | last post: by
68 posts views Thread by stasgold | last post: by
20 posts views Thread by Xavoux | last post: by
26 posts views Thread by vid512 | last post: by
reply views Thread by XIAOLAOHU | last post: by
reply views Thread by lumer26 | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.