473,762 Members | 7,330 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 #1
62 5041
On Fri, 3 Mar 2006 10:19:19 +0800, "Argento" <ar********@hot mail.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.l earn.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*****@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?
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********@hot mail.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_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 #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

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
2917
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
3488
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
3164
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
4661
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
2829
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
11021
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
9521
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
9989
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...
0
9812
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8814
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7360
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6640
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
5268
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
3914
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
3
3510
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2788
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.