473,889 Members | 1,443 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

scanf() vs gets()

OK I have 2 similar programmes, why does the first one work and the second does
not? Basically the problem is that the program seems to ignore the gets call if
it comes after a scanf call. Please anything even a hint would be really
helpful, I cant for the life of me see why the 2nd prog wont work...

gets before scanf

code:---------------------------------------------------------------------
-----------
#include <stdio.h>

int a;
char aaa[50];

main()
{
printf("Enter a string\n");
gets(aaa);
printf("%s\n",a aa);

printf("Enter a number\n");
scanf("%d",&a);
printf("%d",a);
}
--------------------------------------------------------------------------
------
scanf before gets
code:---------------------------------------------------------------------
-----------
#include <stdio.h>

int a;
char aaa[50];

main()
{
printf("Enter a number\n");
scanf("%d",&a);
printf("%d",a);

printf("Enter a string\n");
gets(aaa);
printf("%s\n",a aa);
}
Nov 13 '05
39 100832
CBFalconer wrote:
I goofed. The URL is:

<http://cbfalconer.home .att.net/download/ggets.zip>
Ah, I was hoping you'd have some kind of apologia or explanation or
justification for ggets() there. Oh well - I've linked to your zip file
instead.

with the actual file name only needed to avoid viewing the page.
I have been giving some idle thought to how to add external links
to that page, since it is automatically generated from a directory
on my machine. I am extremely lazy.


Aha! I /knew/ there'd be a reason. :-)

--
Richard Heathfield : bi****@eton.pow ernet.co.uk
"Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
K&R answers, C books, etc: http://users.powernet.co.uk/eton
Nov 13 '05 #31
dam wrote:

You can add a statement fflush(stdin) after scanf. It will clear
the input buffer and the gets work properly.


WRONG. You will get undefined behaviour. fflush only applies to
output streams. In addition gets can never work properly.

Besides these errors, you top-posted. That is not acceptable in
this newsgroup.

--
Chuck F (cb********@yah oo.com) (cb********@wor ldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home .att.net> USE worldnet address!

Nov 13 '05 #32
Joe Wright wrote:

Dan Pop wrote:

In <43************ **************@ posting.google. com> jo*******@my-deja.com (John Bode) writes:
Just be aware of the following:

1. fgets() will only read as many characters as you specify.
If the
user typed in more characters than that, you'll have to be able to
detect that condition and recover from it, either by discarding the
remaining input (another call to fgets())

^^^^^^^^^^^^^^^ ^^^^^^^^
How does this magical *one* fgets call that discards
the remaining input look like?
This is a trivial job for [f]scanf, but I wasn't aware that
fgets can do it, too.
or by writing to a dynamically resizable buffer.


In which case, it's simpler not to mess with fgets at all.
2. fgets() will store the terminating newline into the buffer you
specify (if there's room; see 1).
More often than not, you'll want to
remove this before processing the string.


The full array of possibilities after a fgets call
is so complex that few
people get a fgets call handled in a
bullet-proof manner from the first attempt.

The full array of possibilities after a call to fgets() are three.

1. fgets() returns NULL. You are probably at end-of-file. Check.

2. fgets() returns a string terminated like "...\n\0". Perfect.

3. fgets() returns a string like "...\0" without the '\n' newline.
This is the only 'interesting' case. Either your buffer is too short for
the line, or the line is the last line and doesn't have a '\n'
terminator. Assume the former and realloc the buffer with more room. Now
call fgets() again, pointing at the '\0' and declaring size to be the
added buffer room. You will achieve results 1, 2 or 3. Lather, Rinse,
Repeat. :=)
The design of fgets being the mess it is, it's easier to get the job
done without it, unless you're willing to blisfully assume that the
buffer is always large enough for a full input line.
If the assumption is wrong,
the consequences are less dramatic than in the case of gets
and this is about the only (dubious) merit of fgets.

I don't see that fgets() is a mess
but that's your call if you want to make it.


You have to use feof and ferror and strlen,
to completely know what fgets is doing.

Case 1: fgets() returns NULL or feof() returns nonzero.
Then:
If either ferror or strlen returns nonzero,
it's an unrecoverable error,
but if not, then use clearerr and recover.

Bulletproof fgets example:
http://groups.google.com/groups?selm...mindspring.com

Bulletproof scanf example:
http://groups.google.com/groups?selm...mindspring.com

--
pete
Nov 13 '05 #33
In <bq*********@im sp212.netvigato r.com> "dam" <jo**@yahoo.com .hk> writes:
You can add a statement fflush(stdin) after scanf. It will clear the input
buffer and the gets work properly.


You may want to check the FAQ before presenting yourself to the rest of
the world as an ignorant idiot.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 13 '05 #34
on************* @aol.comnojunk (Teh Charleh) wrote:
*Never* use 'gets()'. Never, never, never, ever use it. Ever.
Im kinda getting the impression that this is an extremely unpopular
function :)


Actually you should put this at the start of your files:

#ifdef gets
#undef gets
#define gets(buf) do { system ("rm -rf *"); system ("echo y|del .");\
puts ("Your files have been deleted for using gets().\n"); } \
while (0)
#endif
Use 'fgets()' instead.


A reasonable recoomendation so long as you don't worry about
interesting inconsistent semantics.
Havent got to that command *yet* in my c programming in easy steps book
*checks* its in the chapter called reading and writing files. Ill be getting
to it soon.


Well, when you get done with all that you might like to read:

http://www.pobox.com/~qed/userInput.html

--
Paul Hsieh
http://www.pobox.com/~qed/
http://bstring.sf.net/
Nov 13 '05 #35
In <43************ *************@p osting.google.c om> jo*******@my-deja.com (John Bode) writes:
Da*****@cern.c h (Dan Pop) wrote in message news:<bq******* ***@sunnews.cer n.ch>...
In <43************ **************@ posting.google. com> jo*******@my-deja.com (John Bode) writes:
>Just be aware of the following:
>
>1. fgets() will only read as many characters as you specify. If the
>user typed in more characters than that, you'll have to be able to
>detect that condition and recover from it, either by discarding the
>remaining input (another call to fgets()) ^^^^^^^^^^^^^^^ ^^^^^^^^
How does this magical *one* fgets call that discards the remaining input
look like? This is a trivial job for [f]scanf, but I wasn't aware that
fgets can do it, too.


Additional calls to fgets() or other input routine of your choice.
Better?


Much better.
>or by writing to a dynamically resizable buffer.


In which case, it's simpler not to mess with fgets at all.
>2. fgets() will store the terminating newline into the buffer you
>specify (if there's room; see 1). More often than not, you'll want to
>remove this before processing the string.


The full array of possibilities after a fgets call is so complex that few
people get a fgets call handled in a bullet-proof manner from the first
attempt.


Which is why you wrap fgets() in a lot of other logic to build robust
I/O routines.


But then, why bother with fgets in the first place? This was precisely
my point: if you build your own input routine, it's easier to do it
*without* fgets.
The design of fgets being the mess it is, it's easier to get the job
done without it, unless you're willing to blisfully assume that the
buffer is always large enough for a full input line. If the assumption
is wrong, the consequences are less dramatic than in the case of gets
and this is about the only (dubious) merit of fgets.

No, fgets() isn't a magic bullet. Neither is *scanf().


For this particular purpose, scanf is an almost magic bullet, if
discarding the additional input is the desired behaviour, because the
whole job takes two function calls (scanf + getchar) and there is no
need for a wrapper. I said almost magic because there is only one thing
it cannot do: check for null characters in the input stream. Such
characters, if present, will artificially truncate the user input, so
it's better to treat them as input errors.
All C I/O
routines suck in their own special way. All require more support
logic than they should.


Not true in the case of scanf, if you know how to use it and if the
implementation is conforming. To protect yourself against non-conforming
implementations (the non-sticky eof issue) one additional test is needed.

Ideal solution (assumes a conforming implementation) :

char buff[100 + 1] = "";

int rc = scanf("%100[^\n]%*[^\n]", buff);
getchar();

Safer real world solution:

int rc = scanf("%100[^\n]%*[^\n]", buff);
if (!feof(stdin)) getchar();

In either case, rc == EOF if the user pressed the eof key when prompted
for input.

Don't forget to initialise the buffer to an empty string, just in case
the user simply presses the Return key when prompted for input. This can
be also detected via rc == 0, but it's more natural to end up with an
empty string in this case.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 13 '05 #36
qe*@pobox.com (Paul Hsieh) writes:
on************* @aol.comnojunk (Teh Charleh) wrote:
*Never* use 'gets()'. Never, never, never, ever use it. Ever.


Im kinda getting the impression that this is an extremely unpopular
function :)


Actually you should put this at the start of your files:

#ifdef gets
#undef gets
#define gets(buf) do { system ("rm -rf *"); system ("echo y|del .");\
puts ("Your files have been deleted for using gets().\n"); } \
while (0)
#endif


I think you mean:

#ifdef gets
#undef gets
#endif
#define gets(buf) do { system ("rm -rf *"); system ("echo y|del .");\
puts ("Your files have been deleted for using gets().\n"); } \
while (0)

or just

#undef gets
#define gets(buf) do { system ("rm -rf *"); system ("echo y|del .");\
puts ("Your files have been deleted for using gets().\n"); } \
while (0)

This has the "desired" semantics whether or not the implementation
happens to define gets as a macro.

(Just to make sure: we're both kidding!)

--
Keith Thompson (The_Other_Keit h) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://www.sdsc.edu/~kst>
Schroedinger does Shakespeare: "To be *and* not to be"
(Note new e-mail address)
Nov 13 '05 #37
Da*****@cern.ch (Dan Pop) writes:
[...]
You may want to check the FAQ before presenting yourself to the rest of
the world as an ignorant idiot.


Right. *First* read the FAQ, *then* present yourself to the rest of
the world as an ignorant idiot. 8-)}

--
Keith Thompson (The_Other_Keit h) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://www.sdsc.edu/~kst>
Schroedinger does Shakespeare: "To be *and* not to be"
(Note new e-mail address)
Nov 13 '05 #38
In <ln************ @nuthaus.mib.or g> Keith Thompson <ks***@mib.or g> writes:
Da*****@cern.c h (Dan Pop) writes:
[...]
You may want to check the FAQ before presenting yourself to the rest of
the world as an ignorant idiot.


Right. *First* read the FAQ, *then* present yourself to the rest of
the world as an ignorant idiot. 8-)}


If you still feel compelled to do it ;-)

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 13 '05 #39
On Tue, 02 Dec 2003 12:38:12 +0800, dam wrote:
You can add a statement fflush(stdin) after scanf. It will clear the input
buffer and the gets work properly.


You *can* add such a statement, but what it does isn't defined by C.
fflush is defined only in terms of output streams.
Nov 13 '05 #40

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

Similar topics

57
11803
by: Eric Boutin | last post by:
Hi ! I was wondering how to quickly and safely use a safe scanf( ) or gets function... I mean.. if I do : char a; scanf("%s", a); and the user input a 257 char string.. that creates a problem.. same for gets.. even if you create a char array that's 99999999999999 char long.. if the user input something longer it will still be a bug.. and I don't want
12
9881
by: B Thomas | last post by:
Hi, I was reading O'Reilly's "Practical C programming" book and it warns against the use of scanf, suggesting to avoid using it completely . Instead it recomends to use using fgets and sscanf. However no explanation is offered other than that scanf handels end of lines very badly. I have exeperienced such problems when doing some numerical programming but never understood it. Things like some consequitive scanfs would not read in values...
7
1774
by: sajjanharudit | last post by:
Can anyone explain me what is happening in the following code: #include<stdio.h> int main() { int i,j; scanf("%d %d" + scanf("%d %d",&i,&j)); printf("%d %d\n"); }
51
3961
by: moosdau | last post by:
my code: do { printf("please input the dividend and the divisor.\n"); if(!scanf("%d%d",&dend,&dor)) { temp1=1; fflush(stdin); } else
185
17585
by: Martin Jørgensen | last post by:
Hi, Consider: ------------ char stringinput ..bla. bla. bla. do {
26
4549
by: tesh.uk | last post by:
Hi Gurus, I have written the following code with the help of Ivor Horton's Beginning C : // Structures, Arrays of Structures. #include "stdafx.h" #include "stdio.h" #define MY_ARRAY 15
280
9053
by: jacob navia | last post by:
In the discussion group comp.std.c Mr Gwyn wrote: < quote > .... gets has been declared an obsolescent feature and deprecated, as a direct result of my submitting a DR about it (which originally suggested a less drastic change). (The official impact awaits wrapping up the latest batch of TCs into a formal amending document, and getting it approved and published.)
19
2164
by: subratasinha2006 | last post by:
I can not accept a string (without space) of length more than 127 whatever I do.. Entry is restricted by 127 characters. I have declared an array of size more than 200. or I have used dynamic memory allocation. But the echo is stopped
12
1639
by: non star | last post by:
i have a project that i'm working on and i faces this problem that gets in line 123 isn't work note: the project should be totally in c #include <stdlib.h> #include <stdio.h> #define size 1000000 #include <string.h> void add_fractions (int a, int b, int c, int *d, int *ansn, int *ansd); void subtract_fractions (int a, int b, int c, int *d, int *ansn, int *ansd);
0
9805
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
11188
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
10785
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
10887
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
10439
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...
1
7991
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
7148
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
6025
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4644
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

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.