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