473,770 Members | 7,229 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

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
62 5052
> 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********@hot mail.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*****@siggrap h.org
http://nuclear.demoscene.gr/
Mar 3 '06 #13
On 2006-03-03, Argento <ar********@hot mail.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*****@siggrap h.org
http://nuclear.demoscene.gr/
Mar 3 '06 #14
On Fri, 3 Mar 2006 16:16:09 +0800, in comp.lang.c , "Argento"
<ar********@hot mail.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********@hot mail.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********@hot mail.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_Keit h) 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********@hot mail.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********@hot mail.com> writes:
"Martin Ambuhl" <ma*****@earthl ink.net> wrote in message
news:bu******** *********@newsr ead3.news.atl.e arthlink.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

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

21
639
by: clusardi2k | last post by:
/* The below code on SGI will wait for you to enter 2 things, but on Linux it will only wait the first time. I can make the code work by replacing the scanf with: char data ; fgets (data,5,stdin); the_number = atoi (data);
20
2921
by: Sivarn | last post by:
I'm writing a program for that takes dates as input using scanf. I want to verify that the user is inputting a full 4 digits for the year. How do I do this? I know that the return value on printf is the number of printed characters; so if I could somehow get my year variable to store the leading zeros, I could just run a check: int dummy = 0; dummy = printf("%d", year);
11
3493
by: TTroy | last post by:
Hello C programmers, Can someone tell me why ungetc can't sent back EOF, but it's sister function getc has no trouble sending it to us? For a file, this might not make a difference, but for an interactive terminal, it is probably nice to push EOF back (because to user doesn't want to provide an EOF twice). How is it getc can send EOF down it's pipe, but we can't send EOF down ungetc's pipe (especially when this pipe is the same)? ...
6
3489
by: Rob Thorpe | last post by:
Given the code:- r = sscanf (s, "%lf", x); What is the correct output if the string s is simply "-" ? If "-" is considered the beginning of a number, that has been cut-short then the correct output is that r = EOF. If it is taken to be a letter in the stream, then the output should be r = 0, as far as I can see. My compiler gives EOF.
33
3167
by: Lalatendu Das | last post by:
Dear friends, I am getting a problem in the code while interacting with a nested Do-while loop It is skipping a scanf () function which it should not. I have written the whole code below. Please help me in finding why such thing is happening and what the remedy to it is. Kindly bear with my English. int main ()
68
4662
by: stasgold | last post by:
Hello. I maybe reinvent the weel ... I'm trying to read positive integer number with the help of scanf, if the input value is not positive number but negaive one zero or char , i have to reread the input until I get the needed pos. number I wrote the code , but it doesn't work the way it should : if i put some char into input, the program goes infinite loop instead of promting me to enter a new value.
27
2833
by: Simon Biber | last post by:
The following Example 3 is given in the 1999 C standard for the function fscanf: I have tested several implementations and none of them get the last case right. In no case does fscanf return 0 indicating failure to match "100ergs of energy" with "%f". The actual behaviour varies. Some will match '100', leaving the 'e' unread:
20
11024
by: Xavoux | last post by:
Hello all... I can't remind which function to use for safe inputs... gets, fgets, scanf leads to buffer overflow... i compiled that code with gcc version 2.95.2, on windows 2000 char tmp0 = "ABCDEFGHI\0"; char buff; /* Input buffer. */ char tmp1 = "ABCDEFGHI\0";
26
9527
by: vid512 | last post by:
hi. i wanted to know why doesn't the scanf functions check for overflow when reading number. For example scanf("%d" on 32bit machine considers "1" and "4294967297" to be the same. I tracked to code to where the conversion itself happens. Code in scanfs just ignores return value from conversion procedures. More info in case of glibc posted here:
0
9592
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
10230
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10058
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10004
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
6678
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5450
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3972
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
3576
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2817
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.