scanf() wierdness

Discussion in 'C Programming' started by Eduardo Olivarez, Jan 23, 2004.

  1. 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>
    Eduardo Olivarez, Jan 23, 2004
    #1
    1. Advertising

  2. Eduardo Olivarez

    Mad Wizard Guest

    In article <vM4Qb.61498$>
    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
    Mad Wizard, Jan 23, 2004
    #2
    1. Advertising

  3. 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
    Darrell Grainger, Jan 25, 2004
    #3
  4. Eduardo Olivarez

    Old Wolf Guest

    Use of malloc()

    > > 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 ?
    Old Wolf, Jan 26, 2004
    #4
  5. 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"?
    Peter Shaggy Haywood, Jan 28, 2004
    #5
  6. Eduardo Olivarez

    Zoran Cutura Guest

    Re: Use of malloc()

    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
    Zoran Cutura, Jan 28, 2004
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Terry Olsen

    Datagrid Cell Spacing Wierdness

    Terry Olsen, Mar 28, 2005, in forum: ASP .Net
    Replies:
    2
    Views:
    555
    Terry Olsen
    Mar 29, 2005
  2. danthman

    Wierdness with "Imports" statement

    danthman, Dec 16, 2005, in forum: ASP .Net
    Replies:
    2
    Views:
    1,181
    danthman
    Dec 16, 2005
  3. Larry
    Replies:
    0
    Views:
    393
    Larry
    Feb 17, 2006
  4. =?ISO-8859-1?Q?Martin_J=F8rgensen?=

    scanf (yes/no) - doesn't work + deprecation errors scanf, fopen etc.

    =?ISO-8859-1?Q?Martin_J=F8rgensen?=, Feb 16, 2006, in forum: C Programming
    Replies:
    185
    Views:
    3,386
    those who know me have no need of my name
    Apr 3, 2006
  5. =?ISO-8859-1?Q?Martin_J=F8rgensen?=

    difference between scanf("%i") and scanf("%d") ??? perhaps bug inVS2005?

    =?ISO-8859-1?Q?Martin_J=F8rgensen?=, Apr 26, 2006, in forum: C Programming
    Replies:
    18
    Views:
    673
    Richard Bos
    May 2, 2006
Loading...

Share This Page