problems writing a printf/scanf function that handles both int and char input from the console

Discussion in 'C Programming' started by Dawn Minnis, Feb 6, 2005.

  1. Dawn Minnis

    Dawn Minnis Guest

    Hi (running Win xp and developing using Miracle C. Running applications in
    windows command prompt)

    I'm new to the group so be gentle with me. I am currently writing a C
    program to perform matrix by matrix (mxm) and matrix by vector (mxv)
    multiplication, so obviously one of my first considerations is to ask the
    user if they want an mxm or mxv multiplication performed. I have written the
    code below (this is a working snippet of the current, substantially larger
    program I am working on. My problem at the moment, is that when I run this
    code and enter any integer from 0-9 it handles the error accordingly and
    iterates around the loop until the values 1 or 2 are entered. Upon which it
    prints "successful response" and finishes (again cut down and missing all
    the other queries and algorithms).

    Now, here comes the problem. When I enter in characters or symbols OTHER
    than integers it spirals into a never ending loop, that I can only exit by
    closing the command prompt window.

    So, can anyone take a quick look at this program and spot for me what I
    assume would be a glaringly obvious reason for this to happen? Such as the
    use of int for the function declaration, or %d when reading in the value.
    But I don't know how to correct the program so that it "accepts" all
    possibilities and then handles them.

    Thanks, kind regards
    Dawn
    -*-*-*-program
    below-*-*-*-
    -----------------------------------------------------------------------------------------------------------

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

    int main()
    {
    int doMMorMV;
    printf("Do you wish to perform MxM or MxV? \nPlease enter 1 for MxM or 2 for
    MxV: ");
    scanf("%d", &doMMorMV);

    while(doMMorMV != 1 && doMMorMV != 2)
    {
    //call reiterative error message 1
    doMMorMV = error1();
    }

    printf("successful response");

    return 0;
    }

    //reiterative error message 1
    int error1()
    {
    int doMMorMV;
    printf("\n Error, not a valid response, \n\t please enter 1 for MxM or 2 for
    MxV: \n");
    scanf("%d", &doMMorMV);
    return doMMorMV;
    }
    Dawn Minnis, Feb 6, 2005
    #1
    1. Advertising

  2. Dawn Minnis

    Mysidia Guest

    Dawn Minnis wrote:

    > int main()
    > {
    > int doMMorMV;
    > printf("Do you wish to perform MxM or MxV? \nPlease enter 1 for MxM

    or 2 for
    > MxV: ");
    > scanf("%d", &doMMorMV);


    Suppose the user enters 'blah'

    Scanf will fail to read an integer, so it
    will return 0, indicating zero items were scanned
    successfully.

    The value in 'doMMorMV' is not changed, since nothing was
    scanned into it, its value is now undefined (could be anything)

    'b' will remain at the start of the input, not consumed
    by this scanf.

    Meaning that the next scanf("%d", &doMMorMV); will also fail,
    hence the endless loop.

    try

    if (scanf("%d", &doMMorMV) < 1) {
    /* Error occured.. */

    /* Note this does not mean the waiting input item has
    been assumed. */
    }

    > while(doMMorMV != 1 && doMMorMV != 2)
    > {
    > //call reiterative error message 1
    > doMMorMV = error1();
    > }
    Mysidia, Feb 6, 2005
    #2
    1. Advertising

  3. Dawn Minnis

    Dawn Minnis Guest

    parsing string input from keyboard to integer

    Thanks for your quick response

    I have spent the last while trying different variations using that but it
    doesn't seem to like it. I have moved on.

    My next challenge is to read in a string and parse it as an integer. I am
    attempting to use the atoi() function but it throws back a weird response.
    eg if I pass it 234 it read in 2my. Any idea why this is?

    also is there a C equivalent to declaring a string?

    I only started programming in C about 3-4 weeks so the function calls are
    very different. what I want to do is like this:

    String userInput;
    int intVal;
    ...
    userInput = System.in.readln();
    intVal = Integer.parseInt(userInput);
    ...

    But thats java. And I need it in C.

    "Mysidia" <> wrote in message
    news:...
    >
    > Dawn Minnis wrote:
    >
    >> int main()
    >> {
    >> int doMMorMV;
    >> printf("Do you wish to perform MxM or MxV? \nPlease enter 1 for MxM

    > or 2 for
    >> MxV: ");
    >> scanf("%d", &doMMorMV);

    >
    > Suppose the user enters 'blah'
    >
    > Scanf will fail to read an integer, so it
    > will return 0, indicating zero items were scanned
    > successfully.
    >
    > The value in 'doMMorMV' is not changed, since nothing was
    > scanned into it, its value is now undefined (could be anything)
    >
    > 'b' will remain at the start of the input, not consumed
    > by this scanf.
    >
    > Meaning that the next scanf("%d", &doMMorMV); will also fail,
    > hence the endless loop.
    >
    > try
    >
    > if (scanf("%d", &doMMorMV) < 1) {
    > /* Error occured.. */
    >
    > /* Note this does not mean the waiting input item has
    > been assumed. */
    > }
    >
    >> while(doMMorMV != 1 && doMMorMV != 2)
    >> {
    >> //call reiterative error message 1
    >> doMMorMV = error1();
    >> }

    >
    Dawn Minnis, Feb 7, 2005
    #3
  4. Dawn Minnis

    CBFalconer Guest

    Re: problems writing a printf/scanf function that handles both int andchar input from the console

    Dawn Minnis wrote:
    >

    .... snip ...
    >
    > Now, here comes the problem. When I enter in characters or symbols
    > OTHER than integers it spirals into a never ending loop, that I can
    > only exit by closing the command prompt window.
    >
    > So, can anyone take a quick look at this program and spot for me
    > what I assume would be a glaringly obvious reason for this to
    > happen? Such as the use of int for the function declaration, or
    > %d when reading in the value. But I don't know how to correct the
    > program so that it "accepts" all possibilities and then handles
    > them.
    >

    .... snip unindented code with over long lines ...
    (because it is too ugly to read)

    In general, if you input values with scanf the char that terminates
    the input or signals that the input cannot be done at all, remains
    in the input stream. You have to get rid of it. Now lets change
    your mechanism to something general (untested code, I am just
    writing things down on the fly). Lets say you want to get one of
    the chars in a specified string and reject everything else.
    Meanwhile you want to prompt with something:

    /* flush stdin until a '\n' or EOF occurs */
    int flushln(void)
    {
    int ch;

    while (('\n' != (ch = getchar())) && (EOF != ch)) continue;
    return ch;
    } /* flushln */

    int getone(const char *prompt, const char* allowed)
    {
    int entered;

    while (1) {
    printf("%s", prompt); fflush(stdout);
    entered = getchar();
    flushln(); /* we only want the first line char */
    if (strchr(allowed, entered)) { /* acceptable */
    return entered; /* so return it */
    }
    else {
    printf("Invalid entry '%c', retry:\n", entered);
    }
    }
    } /* untested */

    Which encapsulates prompting, getting a char, testing validity, and
    retrying until the entry is valid. All assuming I have made no
    silly goofs above.

    So, to get your 1 or 2, you would call:

    doMMorMV = getone("Enter 1 or 2 for M or V", "12");

    which means you have the friendlier method of:

    doMMorMV = getone("Enter M for MM, or V for MV:", "MV");
    or
    doMMorMV = getone("Enter M for MM, or V for MV:", "MmVv");

    with confidence that you are getting something you expect and that
    you have gobbled a complete input line. This simplifies life
    greatly.

    --
    "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
    CBFalconer, Feb 7, 2005
    #4
  5. Re: parsing string input from keyboard to integer

    On Mon, 07 Feb 2005 00:00:31 +0000, Dawn Minnis wrote:

    > Thanks for your quick response
    >
    > I have spent the last while trying different variations using that but it
    > doesn't seem to like it. I have moved on.
    >
    > My next challenge is to read in a string and parse it as an integer. I am
    > attempting to use the atoi() function but it throws back a weird response.
    > eg if I pass it 234 it read in 2my. Any idea why this is?
    >
    > also is there a C equivalent to declaring a string?
    >
    > I only started programming in C about 3-4 weeks so the function calls are
    > very different. what I want to do is like this:
    >
    > String userInput;
    > int intVal;
    > ...
    > userInput = System.in.readln();
    > intVal = Integer.parseInt(userInput);
    > ...
    >
    > But thats java. And I need it in C.


    A good way to read line based input in C is the fgets() function, e.g.

    char buffer[100];

    if ((fgets(buffer, sizeof buffer, stdin) != NULL) {
    int intVal;

    if (sscanf(buffer, "%d", &intVal) != 1) {
    /* Converison failed */
    }
    }

    You could also use atoi() but that doesn't test for invalid input. A
    better function is strtol() which handled bad input including values too
    large, but is a bit more complex to use correctly.

    Lawrence
    Lawrence Kirby, Feb 7, 2005
    #5
  6. Dawn Minnis

    kenuplus Guest

    Re: problems writing a printf/scanf function that handles both int and char input from the console

    Hi.when getchar works,it firstly look at buffer ,If there is somethink
    in buffer
    it use what there is .On the contrary,if there is nothing in buffer,it
    will wait input from user.After, user enter input and
    enter('\n'),getchar only will take input not '\n'.'\n' will stay in
    buffer.when again getchar() works,it will take '\n' at buffer,In other
    words,getchar() won't wait user's input.so if you cope with your
    problem,use flush(stdin) to clear buffer.


    CBFalconer <> wrote in message news:<>...
    > Dawn Minnis wrote:
    > >

    > ... snip ...
    > >
    > > Now, here comes the problem. When I enter in characters or symbols
    > > OTHER than integers it spirals into a never ending loop, that I can
    > > only exit by closing the command prompt window.
    > >
    > > So, can anyone take a quick look at this program and spot for me
    > > what I assume would be a glaringly obvious reason for this to
    > > happen? Such as the use of int for the function declaration, or
    > > %d when reading in the value. But I don't know how to correct the
    > > program so that it "accepts" all possibilities and then handles
    > > them.
    > >

    > ... snip unindented code with over long lines ...
    > (because it is too ugly to read)
    >
    > In general, if you input values with scanf the char that terminates
    > the input or signals that the input cannot be done at all, remains
    > in the input stream. You have to get rid of it. Now lets change
    > your mechanism to something general (untested code, I am just
    > writing things down on the fly). Lets say you want to get one of
    > the chars in a specified string and reject everything else.
    > Meanwhile you want to prompt with something:
    >
    > /* flush stdin until a '\n' or EOF occurs */
    > int flushln(void)
    > {
    > int ch;
    >
    > while (('\n' != (ch = getchar())) && (EOF != ch)) continue;
    > return ch;
    > } /* flushln */
    >
    > int getone(const char *prompt, const char* allowed)
    > {
    > int entered;
    >
    > while (1) {
    > printf("%s", prompt); fflush(stdout);
    > entered = getchar();
    > flushln(); /* we only want the first line char */
    > if (strchr(allowed, entered)) { /* acceptable */
    > return entered; /* so return it */
    > }
    > else {
    > printf("Invalid entry '%c', retry:\n", entered);
    > }
    > }
    > } /* untested */
    >
    > Which encapsulates prompting, getting a char, testing validity, and
    > retrying until the entry is valid. All assuming I have made no
    > silly goofs above.
    >
    > So, to get your 1 or 2, you would call:
    >
    > doMMorMV = getone("Enter 1 or 2 for M or V", "12");
    >
    > which means you have the friendlier method of:
    >
    > doMMorMV = getone("Enter M for MM, or V for MV:", "MV");
    > or
    > doMMorMV = getone("Enter M for MM, or V for MV:", "MmVv");
    >
    > with confidence that you are getting something you expect and that
    > you have gobbled a complete input line. This simplifies life
    > greatly.
    kenuplus, Feb 8, 2005
    #6
  7. Re: problems writing a printf/scanf function that handles both int and char input from the console

    On Tue, 08 Feb 2005 04:15:21 -0800, kenuplus wrote:

    > Hi.when getchar works,it firstly look at buffer ,If there is somethink
    > in buffer
    > it use what there is .On the contrary,if there is nothing in buffer,it
    > will wait input from user.After, user enter input and
    > enter('\n'),getchar only will take input not '\n'.'\n' will stay in
    > buffer.when again getchar() works,it will take '\n' at buffer,In other
    > words,getchar() won't wait user's input.so if you cope with your
    > problem,use flush(stdin) to clear buffer.


    C has no function called flush() and fflush(stdin) is a serious error in
    C, invoking fflush() on input streams invokes undefined behaviour. The
    implication here is that you want to read input by line. A good way of
    doing that is to use fgets() and then parse the input using C's string
    handling facilities.

    Lawrence
    Lawrence Kirby, Feb 8, 2005
    #7
    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. Schnoffos
    Replies:
    2
    Views:
    1,212
    Martien Verbruggen
    Jun 27, 2003
  2. trey

    newbie: char* int and char *int

    trey, Sep 10, 2003, in forum: C Programming
    Replies:
    7
    Views:
    404
    Irrwahn Grausewitz
    Sep 10, 2003
  3. Hal Styli
    Replies:
    14
    Views:
    1,634
    Old Wolf
    Jan 20, 2004
  4. lovecreatesbeauty
    Replies:
    1
    Views:
    1,046
    Ian Collins
    May 9, 2006
  5. eino
    Replies:
    1
    Views:
    432
    =?ISO-8859-15?Q?=22Martin_v=2E_L=F6wis=22?=
    May 8, 2007
Loading...

Share This Page