Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > scanf() wierdness

Reply
Thread Tools

scanf() wierdness

 
 
Eduardo Olivarez
Guest
Posts: n/a
 
      01-23-2004
The following code does not work correctly on my machine. Either one of the
scanf()'s alone work perfectly. However, when they are combined, the second
scanf() call just reads what the first one received as imput, without
taking any keyboard input and then the process terminates prematurely. I
looked through the glibc documentation trying to figure out what was
causing this to no avail, so I started messing around with the code.
Strangely enough, adding a call to getchar() in between the first scanf and
the second printf solves the problem. I have no idea why. Anyone kind
enough to enlighten me as to whats going on?

Non working code (minimized to isolate error):

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

#define STRLEN 100

int main(void) {
int shift;
char *string;

string = (char *) malloc(sizeof(char) * STRLEN);

printf("Input a number: ");
scanf("%d", &shift);
printf("Input a string: ");
scanf("%[^\n]100", string);

printf("%d\n", shift);
printf("%s\n", string);
}

Working code:

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

#define STRLEN 100

int main(void) {
int shift;
char *string;

string = (char *) malloc(sizeof(char) * STRLEN);

printf("Input a number: ");
scanf("%d", &shift);
getchar();
printf("Input a string: ");
scanf("%[^\n]100", string);

printf("%d\n", shift);
printf("%s\n", string);
}

Output of non working code:

remus@phobos remus $ ./test
Input a number: 12
Input a string: 12

remus@phobos remus $

--
Eduardo Olivarez
<ed uardo oli varez at hot mail dot com>
 
Reply With Quote
 
 
 
 
Mad Wizard
Guest
Posts: n/a
 
      01-23-2004
In article <vM4Qb.61498$ m>
Eduardo Olivarez wrote:

If I understand correctly, scanf pushes back at least one
character in the input stream. When you get the number from stdin, you
terminate input with newline character, which is pushed back in the
stdin. When you call scanf second time, it starts to read stdin and the
very first character is newline, so it stops reading.

--
Mad Wizard
 
Reply With Quote
 
 
 
 
Darrell Grainger
Guest
Posts: n/a
 
      01-25-2004
On Fri, 23 Jan 2004, Eduardo Olivarez wrote:

> The following code does not work correctly on my machine. Either one of the
> scanf()'s alone work perfectly. However, when they are combined, the second
> scanf() call just reads what the first one received as imput, without
> taking any keyboard input and then the process terminates prematurely. I
> looked through the glibc documentation trying to figure out what was
> causing this to no avail, so I started messing around with the code.
> Strangely enough, adding a call to getchar() in between the first scanf and
> the second printf solves the problem. I have no idea why. Anyone kind
> enough to enlighten me as to whats going on?


It is more accurate to say that "the followiung code does not do what I
expect on my machine." The problem is usually that it does the correct
thing but that we tend to misunderstand what the correct thing it.

> Non working code (minimized to isolate error):
>
> #include <stdio.h>
> #include <stdlib.h>
> #include <ctype.h>
>
> #define STRLEN 100
>
> int main(void) {
> int shift;
> char *string;
>
> string = (char *) malloc(sizeof(char) * STRLEN);


You shouldn't need the cast. If you failed to #include <stdlib.h> the
compiler will assume that malloc returns an int and that you want to cast
the int to a pointer to char. This is undefined behaviour. Just don't cast
the result of malloc. It should be returning a pointer to void and not
need the cast.

Additionally, sizeof(char) is always 1. Seems redundant to use it here.

> printf("Input a number: ");


Add a fflush(stdout); after the printf. Search the newsgroup for
'fflush(stdout)' and you'll probably find the explanation as to why.

> scanf("%d", &shift);


If the user inputs "123\n" then scanf will read the "123", convert it to
123 and assign it to shift. The "\n" can remain on the stream.

> printf("Input a string: ");
> scanf("%[^\n]100", string);


This indicates to read 100 char until you reach a newline character. The
last scanf left the '\n' in the stream so this quits immediate and returns
0. You should check the return value of scanf and see if it was
successful. Your code below assumes it was. Don't assume when you can
check.

> printf("%d\n", shift);
> printf("%s\n", string);


return 0;

> }


It is usually better to use fgets() to read in a line from the user then
use sscanf to scan the string. This will 'flush' the newline character
from the stdin stream.

> Working code:
>
> #include <stdio.h>
> #include <stdlib.h>
> #include <ctype.h>
>
> #define STRLEN 100
>
> int main(void) {
> int shift;
> char *string;
>
> string = (char *) malloc(sizeof(char) * STRLEN);
>
> printf("Input a number: ");
> scanf("%d", &shift);
> getchar();


This is a hack. Without understanding why you need this you should assume
the code still does not work. You can only assume it APPEARS to work. On
future runs it might fail.

> printf("Input a string: ");
> scanf("%[^\n]100", string);
>
> printf("%d\n", shift);
> printf("%s\n", string);
> }
>
> Output of non working code:
>
> remus@phobos remus $ ./test
> Input a number: 12
> Input a string: 12
>
> remus@phobos remus $
>
> --
> Eduardo Olivarez
> <ed uardo oli varez at hot mail dot com>
>


--
Send e-mail to: darrell at cs dot toronto dot edu
Don't send e-mail to
 
Reply With Quote
 
Old Wolf
Guest
Posts: n/a
 
      01-26-2004
> > string = (char *) malloc(sizeof(char) * STRLEN);
>
> You shouldn't need the cast. If you failed to #include <stdlib.h> the
> compiler will assume that malloc returns an int and that you want to cast
> the int to a pointer to char. This is undefined behaviour. Just don't cast
> the result of malloc. It should be returning a pointer to void and not
> need the cast.
>
> Additionally, sizeof(char) is always 1. Seems redundant to use it here.


Argh. I count 6 different active threads (posted to in the last
24 hours) where someone has "corrected" someone else's non-buggy
use of malloc(). Perhaps we need a new group, comp.lang.c.malloc ?
 
Reply With Quote
 
Peter Shaggy Haywood
Guest
Posts: n/a
 
      01-28-2004
Groovy hepcat Eduardo Olivarez was jivin' on Fri, 23 Jan 2004 08:17:31
GMT in comp.lang.c.
scanf() wierdness's a cool scene! Dig it!

>The following code does not work correctly on my machine. Either one of the
>scanf()'s alone work perfectly. However, when they are combined, the second
>scanf() call just reads what the first one received as imput, without


READ THE FAQ!!! The FAQ exists for a reason: to answer questions
like this. Yet we still have to constantly tell people to read the
FAQ. This should be taken for granted, but no! You should also read
the newsgroup for some time. Your question is answered all the time.
You would know that if you had lurked here and read the FAQ, as you
should have done. It is very rude to post to a newsgroup without first
lurking for a while and reading its FAQ.
If I sound mean I'm sorry, but I'm tired of telling people to lurk
and read the FAQ. It should be the first thing you do when you enter a
newsgroup for the first time.
Lurk and ye shall see the FAQs.

--

Dig the even newer still, yet more improved, sig!

http://alphalink.com.au/~phaywood/
"Ain't I'm a dog?" - Ronny Self, Ain't I'm a Dog, written by G. Sherry & W. Walker.
I know it's not "technically correct" English; but since when was rock & roll "technically correct"?
 
Reply With Quote
 
Zoran Cutura
Guest
Posts: n/a
 
      01-28-2004
Old Wolf <> wrote:
>> > string = (char *) malloc(sizeof(char) * STRLEN);

>>
>> You shouldn't need the cast. If you failed to #include <stdlib.h> the
>> compiler will assume that malloc returns an int and that you want to cast
>> the int to a pointer to char. This is undefined behaviour. Just don't cast
>> the result of malloc. It should be returning a pointer to void and not
>> need the cast.
>>
>> Additionally, sizeof(char) is always 1. Seems redundant to use it here.

>
> Argh. I count 6 different active threads (posted to in the last
> 24 hours) where someone has "corrected" someone else's non-buggy
> use of malloc(). Perhaps we need a new group, comp.lang.c.malloc ?


Oh, actually I think CLC considers such usage of malloc to be buggy.
There are arguments against such usage and as some say there are for.
But I personally do not understand those who say that you should cast
mallocs return value.
Why would you say someone should cast malloc?

--
Z ()
"LISP is worth learning for the profound enlightenment experience
you will have when you finally get it; that experience will make you
a better programmer for the rest of your days." -- Eric S. Raymond
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Application_Error wierdness in asp.net development server (VS.Net 2005) Larry ASP .Net 0 02-17-2006 05:20 PM
Wierdness with "Imports" statement danthman ASP .Net 2 12-16-2005 01:19 AM
Cisco 837 and Cisco VPN client wierdness.. any ideas? Christian Hewitt Cisco 1 04-30-2005 11:33 AM
AS5359 IP address Wierdness Jason Cisco 0 04-08-2005 04:49 PM
Datagrid Cell Spacing Wierdness Terry Olsen ASP .Net 2 03-29-2005 01:57 AM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57