how to check the scanf function if it will read more than one number

Discussion in 'C Programming' started by moosdau, Jan 2, 2006.

  1. moosdau

    moosdau Guest

    my code:
    do
    {
    printf("please input the dividend and the divisor.\n");
    if(!scanf("%d%d",&dend,&dor))
    {
    temp1=1;
    fflush(stdin);
    }
    else
    temp1=0;
    }while(temp1==1);

    it seems that it only depend on the first number it read.
    if I input " a 32 ", it could know there is a error,
    but if I input " 32 a ",
    it accept that.

    thanks in advance.
     
    moosdau, Jan 2, 2006
    #1
    1. Advertising

  2. moosdau

    tmp123 Guest

    moosdau wrote:
    > my code:
    > do
    > {
    > printf("please input the dividend and the divisor.\n");
    > if(!scanf("%d%d",&dend,&dor))
    > {
    > temp1=1;
    > fflush(stdin);
    > }
    > else
    > temp1=0;
    > }while(temp1==1);
    >
    > it seems that it only depend on the first number it read.
    > if I input " a 32 ", it could know there is a error,
    > but if I input " 32 a ",
    > it accept that.
    >
    > thanks in advance.



    Hi,

    In "man scanf", I suggest you to read chapter "return values".

    Kind regards.
     
    tmp123, Jan 2, 2006
    #2
    1. Advertising

  3. moosdau

    moosdau Guest

    do you mean the linux os?
    but I'm using windows,so I can't use the "man" command.
    could you tell me plz?
     
    moosdau, Jan 2, 2006
    #3
  4. Re: how to check the scanf function if it will read more than onenumber

    moosdau wrote:
    > do you mean the linux os?
    > but I'm using windows,so I can't use the "man" command.
    > could you tell me plz?

    For windows, look up the function at
    http://msdn.microsoft.com/

    (A little hint is that scanf returns the nr of successfully
    assigned items)
     
    =?ISO-8859-1?Q?=22Nils_O=2E_Sel=E5sdal=22?=, Jan 2, 2006
    #4
  5. Re: how to check the scanf function if it will read more than onenumber

    "moosdau" <> writes:
    > my code:
    > do
    > {
    > printf("please input the dividend and the divisor.\n");
    > if(!scanf("%d%d",&dend,&dor))
    > {
    > temp1=1;
    > fflush(stdin);
    > }
    > else
    > temp1=0;
    > }while(temp1==1);
    >
    > it seems that it only depend on the first number it read.
    > if I input " a 32 ", it could know there is a error,
    > but if I input " 32 a ",
    > it accept that.


    scanf() returns the number of items assigned. If you give it " 32 a ",
    it will assign 32 to dend and fail to assign a value to dor; scanf()
    will then return 1. If you want to assign both values, you need to
    check whether scanf() returned 2.

    You should pick a better name than "temp1". The simplest thing to do
    is to assign the result of scan() to a variable, and test the value
    of that variable. Pseudo-code follows:

    do {
    printf("...\n");
    items_read = scanf(...);
    } while (items_read != 2);

    Don't use fflush(stdin). The fflush() function is defined only for
    output streams.

    scanf() can be very tricky, it can leave unread garbage in your input
    stream, and it can be difficult to figure out just what it's doing. A
    better approach is to use fgets() to read an entire line, then use
    sscanf() to get information from the line you've read.

    --
    Keith Thompson (The_Other_Keith) <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.
     
    Keith Thompson, Jan 2, 2006
    #5
  6. moosdau

    tmp123 Guest

    moosdau wrote:
    > do you mean the linux os?
    > but I'm using windows,so I can't use the "man" command.
    > could you tell me plz?


    Mna pages are also available in hundreds of www servers.
     
    tmp123, Jan 2, 2006
    #6
  7. moosdau

    Chuck F. Guest

    Re: how to check the scanf function if it will read more than onenumber

    moosdau wrote:
    >
    > do you mean the linux os? but I'm using windows,so I can't use
    > the "man" command. could you tell me plz?


    Include context. Without it we have no idea what you mean. See my
    sig, and the reference therein, for how to do this.

    On Windoze you are probably either using Microsoft VC, or some port
    of GCC. With the gcc versions you very likely have info (the
    command) available, especially if you have installed DJGPP or
    Cygwin. Otherwise the VC help system will probably lead you to a
    discussion of scanf.

    On this windoze system the command:

    C>info libc alpha scanf

    brings up a screen that begins as follows:

    scanf
    =====

    Syntax
    ------

    #include <stdio.h>

    int scanf(const char *format, ...);

    Description
    -----------

    This function scans formatted text from `stdin' and stores it in
    the variables pointed to by the arguments. *Note scanf::.
    .... and so forth ...

    --
    "If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers." - Keith Thompson
    More details at: <http://cfaj.freeshell.org/google/>
     
    Chuck F., Jan 2, 2006
    #7
  8. moosdau

    moosdau Guest

    Keith Thompson wrote:
    > scanf() returns the number of items assigned. If you give it " 32 a ",
    > it will assign 32 to dend and fail to assign a value to dor; scanf()
    > will then return 1. If you want to assign both values, you need to
    > check whether scanf() returned 2.
    >
    > You should pick a better name than "temp1". The simplest thing to do


    sorry,because I copied it from a long code,
    if I named every variant with its meaning, there must be too many
    temporary variants.
    so ......

    > is to assign the result of scan() to a variable, and test the value
    > of that variable. Pseudo-code follows:
    >
    > do {
    > printf("...\n");
    > items_read = scanf(...);
    > } while (items_read != 2);
    >
    > Don't use fflush(stdin). The fflush() function is defined only for
    > output streams.



    Thanks very much!!
    but I don't know very clearly why shouldn't I use the fflush function.
    if there is not any usable data in the input stream,
    could I use it to clear the input stream?
    if not , could you please tell me why?


    > scanf() can be very tricky, it can leave unread garbage in your input
    > stream, and it can be difficult to figure out just what it's doing. A
    > better approach is to use fgets() to read an entire line, then use
    > sscanf() to get information from the line you've read.


    thanks for your suggestion!


    > --
    > Keith Thompson (The_Other_Keith) <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.
     
    moosdau, Jan 2, 2006
    #8
  9. moosdau said:

    <snip>

    > [...] I don't know very clearly why shouldn't I use the fflush function.
    > if there is not any usable data in the input stream,


    Because fflush's behaviour is only defined for streams open for output or
    update.

    > could I use it to clear the input stream?


    Not as far as the C language is concerned, no.

    > if not , could you please tell me why?


    For the same reason that pressing the handle on your toilet will not get rid
    of the water waiting in your sink's tap (or faucet, if you're on that side
    of the pond). Flushing is something we do to output, not to input.

    If you want to discard from stdin everything up to and including a
    particular character, you can use this function:

    #include <stdio.h>

    int DiscardFromStream(FILE *fp, int lim)
    {
    int ch;
    while((ch = getc(fp)) != lim && ch != EOF)
    {
    continue;
    }
    return ch == EOF;
    }

    /* example usage */
    int main(void)
    {
    int ch;
    puts("Type a letter, and press ENTER.");
    ch = getchar();
    if(0 == DiscardFromStream(stdin, '\n'))
    {
    printf("You pressed %c\n", ch);
    puts("Type another letter, and press ENTER.");
    ch = getchar();
    if(0 == DiscardFromStream(stdin, '\n'))
    {
    printf("You pressed %c\n", ch);
    }
    }
    return 0;
    }

    --
    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)
     
    Richard Heathfield, Jan 2, 2006
    #9
  10. moosdau

    pemo Guest

    "moosdau" <> wrote in message
    news:...
    >


    >
    > Thanks very much!!
    > but I don't know very clearly why shouldn't I use the fflush function.
    > if there is not any usable data in the input stream,
    > could I use it to clear the input stream?
    > if not , could you please tell me why?


    There's no easy way to purge stdin, esp when it's already potentially empty,
    i.e., most [all that I can think of right now] std functions that could
    potentially test for this will *wait* if stdin is empty, e.g., getchar,
    scanf, gets, fgets, feof, ... it's a toughie, and I would suggest that, *if*
    your code need *not* be portable, and *if* your implementation of fflush
    works on stdin ok, well, you should perhaps stick with it then! I'll get
    flamed for suggesting this of course - or - better still, someone will come
    up with a portable way to flush stdin ;-)
     
    pemo, Jan 2, 2006
    #10
  11. pemo said:

    > I would suggest
    > that, *if* your code need *not* be portable, and *if* your implementation
    > of fflush works on stdin ok, well, you should perhaps stick with it then!


    Bad advice. Better to avoid the problem completely, which is trivial.

    > I'll get flamed for suggesting this of course - or - better still,
    > someone will come up with a portable way to flush stdin ;-)


    That doesn't make sense, since flushing is not something we do to input.
    I've already posted a portable way to discard characters from stdin until a
    delimiter is encountered.

    I never, ever have to solve this problem in my own code, because I capture
    all text input a line at a time. Why don't you just do that too?

    --
    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)
     
    Richard Heathfield, Jan 2, 2006
    #11
  12. moosdau

    Flash Gordon Guest

    Re: how to check the scanf function if it will read more than onenumber

    moosdau wrote:
    > Keith Thompson wrote:
    >> scanf() returns the number of items assigned. If you give it " 32 a ",
    >> it will assign 32 to dend and fail to assign a value to dor; scanf()
    >> will then return 1. If you want to assign both values, you need to
    >> check whether scanf() returned 2.
    >>
    >> You should pick a better name than "temp1". The simplest thing to do

    >
    > sorry,because I copied it from a long code,
    > if I named every variant with its meaning, there must be too many
    > temporary variants.
    > so ......


    If that is a problem it sounds like your function is too long and it
    should be split in to multiple functions.

    >> is to assign the result of scan() to a variable, and test the value
    >> of that variable. Pseudo-code follows:
    >>
    >> do {
    >> printf("...\n");
    >> items_read = scanf(...);
    >> } while (items_read != 2);
    >>
    >> Don't use fflush(stdin). The fflush() function is defined only for
    >> output streams.

    >
    > Thanks very much!!
    > but I don't know very clearly why shouldn't I use the fflush function.
    > if there is not any usable data in the input stream,
    > could I use it to clear the input stream?
    > if not , could you please tell me why?


    <snip>

    You should not use it in input streams because it is not defined. That
    means anything can happen, from what you expect to your computer growing
    arms and hands and punching you in the nose. More likely effects, if it
    appears to work on your current system, are you doing an update and it
    suddenly not doing what you expect but either doing nothing or giving
    some kind of access violation error.

    If you want to clear the input stream you have to decide on what you
    mean, possibly reading the rest of the line, and do that. If you really
    do want to throw away anything the user has typed so far (what if input
    is piped in from a file though!) and get the next thing the user types,
    then you can't do that in standard C and will have to use system
    specific routines.
    --
    Flash Gordon
    Living in interesting times.
    Although my email address says spam, it is real and I read it.
     
    Flash Gordon, Jan 2, 2006
    #12
  13. moosdau

    pemo Guest

    "Richard Heathfield" <> wrote in message
    news:dpb9pp$d92$-infra.bt.com...
    > pemo said:
    >
    >> I would suggest
    >> that, *if* your code need *not* be portable, and *if* your implementation
    >> of fflush works on stdin ok, well, you should perhaps stick with it then!

    >
    > Bad advice. Better to avoid the problem completely, which is trivial.


    But, I'd wager, not as trivial as scanf("%d", &n); fflush(stdin); if it were
    fully supported? Aren't you talkig about something like this?

    char buffer[100];

    int n;

    if(fgets(buffer, sizeof(buffer), stdin))
    {
    if(sscanf(buffer, "%d", &n))
    {
    printf("w00t, we read an int! (%d)\n", n);
    }
    }

    >> I'll get flamed for suggesting this of course - or - better still,
    >> someone will come up with a portable way to flush stdin ;-)

    >
    > That doesn't make sense, since flushing is not something we do to input.
    > I've already posted a portable way to discard characters from stdin until
    > a
    > delimiter is encountered.


    I know what you mean [the 'logic' of it], but as this scanf type question is
    often asked here, it obviously does make sense in that context - e.g., since
    scanf is provided, and as that function is invariably the function that's
    used in tutorials, it *would* make sense [surely?] to have some way of
    removing any unread characters held in the stdin stream?

    > I never, ever have to solve this problem in my own code, because I capture
    > all text input a line at a time. Why don't you just do that too?


    Sure, it's a good way to handle the problem, but see my wager.
     
    pemo, Jan 2, 2006
    #13
  14. moosdau

    Chuck F. Guest

    Re: how to check the scanf function if it will read more than onenumber

    pemo wrote:
    >

    .... snip ...
    >
    > I know what you mean [the 'logic' of it], but as this scanf type
    > question is often asked here, it obviously does make sense in
    > that context - e.g., since scanf is provided, and as that
    > function is invariably the function that's used in tutorials, it


    Not in good tutorials.

    > *would* make sense [surely?] to have some way of removing any
    > unread characters held in the stdin stream?


    We do. My variant of Richards function is:

    int flushln(FILE *f)
    {
    int ch;

    do {
    ch = getc(f);
    } while (('\n' != ch) && (EOF != ch));
    return ch;
    }

    --
    "If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers." - Keith Thompson
    More details at: <http://cfaj.freeshell.org/google/>
     
    Chuck F., Jan 2, 2006
    #14
  15. moosdau

    pemo Guest

    "Chuck F. " <> wrote in message
    news:...
    > pemo wrote:
    >>

    > ... snip ...
    >>
    >> I know what you mean [the 'logic' of it], but as this scanf type
    >> question is often asked here, it obviously does make sense in
    >> that context - e.g., since scanf is provided, and as that
    >> function is invariably the function that's used in tutorials, it

    >
    > Not in good tutorials.


    I didn't think that there were any????

    >> *would* make sense [surely?] to have some way of removing any
    >> unread characters held in the stdin stream?

    >
    > We do. My variant of Richards function is:
    >
    > int flushln(FILE *f)
    > {
    > int ch;
    >
    > do {
    > ch = getc(f);
    > } while (('\n' != ch) && (EOF != ch));
    > return ch;
    > }


    Would this be acceptable for stdin?

    void flushstdin(void)
    {
    while(getchar() != '\n')
    ;

    return;
    }
     
    pemo, Jan 2, 2006
    #15
  16. Re: how to check the scanf function if it will read more than onenumber

    moosdau a écrit :
    > do you mean the linux os?
    > but I'm using windows,so I can't use the "man" command.
    > could you tell me plz?


    google 'man <item>' works too...

    --
    A+

    Emmanuel Delahaye
     
    Emmanuel Delahaye, Jan 2, 2006
    #16
  17. Re: how to check the scanf function if it will read more than onenumber

    pemo a écrit :
    > There's no easy way to purge stdin, esp when it's already potentially empty,
    > i.e., most [all that I can think of right now] std functions that could
    > potentially test for this will *wait* if stdin is empty, e.g., getchar,
    > scanf, gets, fgets, feof, ... it's a toughie, and I would suggest that, *if*
    > your code need *not* be portable, and *if* your implementation of fflush
    > works on stdin ok, well, you should perhaps stick with it then! I'll get
    > flamed for suggesting this of course - or - better still, someone will come
    > up with a portable way to flush stdin ;-)


    It's a design issue. Using the proper input function in the proper way
    avoids these problems of pending characters. The canonic way :

    char line[PROPER_SIZE];

    if (fgets(line, sizeof line, stdin) != NULL)
    {
    /* search */
    char *p = strchr(line, '\n');
    if (p != NULL)
    {
    /* kill */
    *p = 0;
    }
    else
    {
    /* purge */
    int c;
    while ((c = fgetc(stdin)) != '\n' && c != EOF)
    {
    }
    }
    }

    stick this into some getline() function of your own, add the required
    headers (<stdio.h> and <string.h>) and you have a decent input function
    for life.

    --
    A+

    Emmanuel Delahaye
     
    Emmanuel Delahaye, Jan 2, 2006
    #17
  18. Re: how to check the scanf function if it will read more than onenumber

    "pemo" <> writes:
    > "Chuck F. " <> wrote in message
    > news:...

    [...]
    >> We do. My variant of Richards function is:
    >>
    >> int flushln(FILE *f)
    >> {
    >> int ch;
    >>
    >> do {
    >> ch = getc(f);
    >> } while (('\n' != ch) && (EOF != ch));
    >> return ch;
    >> }

    >
    > Would this be acceptable for stdin?
    >
    > void flushstdin(void)
    > {
    > while(getchar() != '\n')
    > ;
    >
    > return;
    > }


    What if getchar() returns EOF before returning '\n'?

    Note that there are two different things being discussed here. One,
    which is easily implementable in standard C, is discarding all the
    remaining characters in a line. The other, which can't be done in
    standard C, is discarding all typed characters that haven't been
    processed yet, i.e., flushing the typeahead buffer.

    I think the former is what the OP really wants.

    --
    Keith Thompson (The_Other_Keith) <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.
     
    Keith Thompson, Jan 2, 2006
    #18
  19. moosdau

    pemo Guest

    "Keith Thompson" <> wrote in message
    news:...
    > "pemo" <> writes:
    >> "Chuck F. " <> wrote in message
    >> news:...

    > [...]
    >>> We do. My variant of Richards function is:
    >>>
    >>> int flushln(FILE *f)
    >>> {
    >>> int ch;
    >>>
    >>> do {
    >>> ch = getc(f);
    >>> } while (('\n' != ch) && (EOF != ch));
    >>> return ch;
    >>> }

    >>
    >> Would this be acceptable for stdin?
    >>
    >> void flushstdin(void)
    >> {
    >> while(getchar() != '\n')
    >> ;
    >>
    >> return;
    >> }

    >
    > What if getchar() returns EOF before returning '\n'?


    Surely, if there's a \n in the buffer, getchar won't return EOF?

    If there's not a \n in the buffer, I can see that testing for EOF might be a
    good idea.
     
    pemo, Jan 2, 2006
    #19
  20. Re: how to check the scanf function if it will read more than onenumber

    pemo a écrit :
    > Would this be acceptable for stdin?
    >
    > void flushstdin(void)
    > {
    > while(getchar() != '\n')
    > ;
    >
    > return;
    > }


    No, because stdin can be redirected from a file. EOF must be checked too.

    Note that the 'return;' is useless.

    --
    A+

    Emmanuel Delahaye
     
    Emmanuel Delahaye, Jan 2, 2006
    #20
    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. mayur
    Replies:
    2
    Views:
    1,032
    Natty Gur
    Jul 2, 2004
  2. Merciadri Luca
    Replies:
    4
    Views:
    835
  3. Bob Rashkin
    Replies:
    5
    Views:
    85
    Dennis Lee Bieber
    Dec 23, 2013
  4. Steven D'Aprano
    Replies:
    0
    Views:
    116
    Steven D'Aprano
    Dec 23, 2013
  5. Replies:
    3
    Views:
    98
    Gary Herron
    Dec 23, 2013
Loading...

Share This Page