Menu printed twice in calc prog

Discussion in 'C Programming' started by Andy, Nov 6, 2003.

  1. Andy

    Andy Guest

    Hi

    I am writing a small calculator program using switch() for a menu. The
    menu is presented at first, selection read in via scanf(), and
    calculation is executed. At the end of the operation, the menu is
    presented again. When it is presented again however, it is printed
    twice. I've been through the code and cannot spot any obvious errors,
    but hey ... more eyes are better than one. I don't particularly want to
    revamp my code too much nor use sophisticated hacks since I am a student
    relatively new to C and programming and a lot of that advanced stuff
    would be way over my head :)

    I have copied the code for reference. Does it have something with not
    flushing the buffers from the first stdin read by scanf()? Suggestions
    please:

    ----------code begin--------------------

    /****************************************************************
    * *
    * Program: Calk-U-l8r.c *
    * *
    * Written by: xxxxxxxxxxxx *
    * *
    * 30/10/03; <version number> *
    * *
    *****************************************************************/


    #include <stdio.h>

    /* Menu-driven Calculator program: */


    main()

    {
    float i, z, tmp;
    char x;

    tmp = 0;

    puts("\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n");
    puts("\n Calk-U-l8r\n");
    puts("\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n");

    puts("\nPlease select an operation. Enter 'q' to quit:"); /* menu */
    printf("\nAdd: %10c\n", 'a');
    printf("Divide: %7c\n", 'd');
    printf("Multiply: %5c\n", 'm');
    printf("Subtract: %5c\n", 's');

    scanf("%c", &x);

    while ( x != 'q'){
    switch(x){
    case 'a': /* add function */
    puts("\nAddition\n");
    printf("\nEnter digit:>");
    scanf("%f", &i);
    tmp += i;
    printf("\nEnter next digit:>");
    scanf("%f", &i);
    tmp += i;

    printf("\nThe answer is: %.2f", tmp);
    break;

    case 'd': /* divide function */
    puts("\nDivision\n");
    puts("\nEnter a digit:");
    scanf("%f", &i);
    puts("\nEnter the dividend:");
    scanf("%f", &z);

    printf("\nThe answer is: %.2f", i / z);
    break;

    case 'm': /* multiplication */
    puts("\nMultiplication\n");
    printf("\nEnter a digit:>");
    scanf("%f", &i);
    printf("\nEnter a second digit:>");
    scanf("%f", &z);

    printf("\nThe answer is: %.2f", i * z);
    break;

    case 's': /* subtraction */
    puts("\nSubtraction\n");
    puts("\nEnter a digit:");
    scanf("%f", &i);
    puts("\nEnter second digit:");
    scanf("%f", &z);

    printf("\nThe answer is: %.2f", i - z);
    break;

    }


    puts("\nPlease select an operation. Enter 'q' to quit:");
    printf("\nAdd: %10c\n", 'a');
    printf("Divide: %7c\n", 'd');
    printf("Multiply: %5c\n", 'm');
    printf("Subtract: %5c\n", 's');

    scanf("%c", &x);

    }

    puts("\n\nThank-you for using Calk-U-l8r!\n");

    return 0;

    }


    ----------code end------------------------

    Thanks

    Andy
     
    Andy, Nov 6, 2003
    #1
    1. Advertising

  2. Andy

    Eric Sosman Guest

    Andy wrote:
    >
    > Hi
    >
    > I am writing a small calculator program using switch() for a menu. The
    > menu is presented at first, selection read in via scanf(), and
    > calculation is executed. At the end of the operation, the menu is
    > presented again. When it is presented again however, it is printed
    > twice. I've been through the code and cannot spot any obvious errors,
    > but hey ... more eyes are better than one. I don't particularly want to
    > revamp my code too much nor use sophisticated hacks since I am a student
    > relatively new to C and programming and a lot of that advanced stuff
    > would be way over my head :)
    >
    > I have copied the code for reference. Does it have something with not
    > flushing the buffers from the first stdin read by scanf()? Suggestions
    > please:
    > [code snipped; see up-thread]


    Your suspicion is close to the mark, and your problem
    is pretty close to that of Question 12.18 in the comp.lang.c
    Frequently Asked Questions (FAQ) list

    http://www.eskimo.com/~scs/C-faq/top.html

    .... but perhaps just enough different to warrant extra
    explanation. Here's a synopsis of what's happening:

    - You print the menu, and then call scanf() to get
    the user's choice.

    - scanf() converts one character, and you add or
    subtract or whatever in response.

    - You print the menu again, and call scanf() to get
    the user's choice.

    - scanf() again converts one character -- but what
    character is that, exactly? Why, it's the newline
    that ended the user's first line of input. This
    '\n' character doesn't match anything in your big
    switch() statement, so you take no action on it.

    - After having done nothing, you print the menu
    and call scanf() a third time.

    - This time, scanf() consumes the character after
    the newline, namely, the user's actual response,
    and you process it.

    - ... and then you print the menu, consume and ignore
    the newline, print the menu again, consume and act
    upon the user's choice, and so on.

    See Questions 12.17 through 12.20 for some ideas of
    what you might do differently. My preference is not to use
    scanf() at all for interactive input; when data comes from
    an "uncontrolled" source, I prefer to read an entire line
    at a time with fgets() or something similar, and then pick
    the line apart without further I/O. fgets() plus sscanf()
    makes a pretty good pairing, combining the apparent ease of
    plain scanf() with a more predictable I/O behavior.

    --
     
    Eric Sosman, Nov 6, 2003
    #2
    1. Advertising

  3. Andy

    Andy Guest

    Eric Sosman wrote:
    >
    >
    > Your suspicion is close to the mark, and your problem
    > is pretty close to that of Question 12.18 in the comp.lang.c
    > Frequently Asked Questions (FAQ) list
    >
    > http://www.eskimo.com/~scs/C-faq/top.html
    >
    > .... but perhaps just enough different to warrant extra
    > explanation. Here's a synopsis of what's happening:
    >
    > - You print the menu, and then call scanf() to get
    > the user's choice.
    >
    > - scanf() converts one character, and you add or
    > subtract or whatever in response.
    >
    > - You print the menu again, and call scanf() to get
    > the user's choice.
    >
    > - scanf() again converts one character -- but what
    > character is that, exactly? Why, it's the newline
    > that ended the user's first line of input. This
    > '\n' character doesn't match anything in your big
    > switch() statement, so you take no action on it.
    >
    > - After having done nothing, you print the menu
    > and call scanf() a third time.
    >
    > - This time, scanf() consumes the character after
    > the newline, namely, the user's actual response,
    > and you process it.
    >
    > - ... and then you print the menu, consume and ignore
    > the newline, print the menu again, consume and act
    > upon the user's choice, and so on.
    >
    > See Questions 12.17 through 12.20 for some ideas of
    > what you might do differently. My preference is not to use
    > scanf() at all for interactive input; when data comes from
    > an "uncontrolled" source, I prefer to read an entire line
    > at a time with fgets() or something similar, and then pick
    > the line apart without further I/O. fgets() plus sscanf()
    > makes a pretty good pairing, combining the apparent ease of
    > plain scanf() with a more predictable I/O behavior.
    >

    Eric
    Thanks for your response - that was nicely explained and useful. I would
    have googled for the solution but to be honest didn't really know what
    to put in the search string over and above any generality (like scanf())
    that would have generated x number of hits. I will look at the FAQ you
    mention and see what I can come up with. I've never used fgets() before,
    so that will be a useful technique to examine.

    Much obliged.

    - Andy
     
    Andy, Nov 7, 2003
    #3
  4. "Andy" <> wrote in message news:3fab4d59@212.67.96.135...
    > Eric Sosman wrote:
    > >
    > >
    > > Your suspicion is close to the mark, and your problem
    > > is pretty close to that of Question 12.18 in the comp.lang.c
    > > Frequently Asked Questions (FAQ) list
    > >
    > > http://www.eskimo.com/~scs/C-faq/top.html
    > >
    > > .... but perhaps just enough different to warrant extra
    > > explanation. Here's a synopsis of what's happening:
    > >
    > > - You print the menu, and then call scanf() to get
    > > the user's choice.
    > >
    > > - scanf() converts one character, and you add or
    > > subtract or whatever in response.
    > >
    > > - You print the menu again, and call scanf() to get
    > > the user's choice.
    > >
    > > - scanf() again converts one character -- but what
    > > character is that, exactly? Why, it's the newline
    > > that ended the user's first line of input. This
    > > '\n' character doesn't match anything in your big
    > > switch() statement, so you take no action on it.
    > >
    > > - After having done nothing, you print the menu
    > > and call scanf() a third time.
    > >
    > > - This time, scanf() consumes the character after
    > > the newline, namely, the user's actual response,
    > > and you process it.
    > >
    > > - ... and then you print the menu, consume and ignore
    > > the newline, print the menu again, consume and act
    > > upon the user's choice, and so on.
    > >
    > > See Questions 12.17 through 12.20 for some ideas of
    > > what you might do differently. My preference is not to use
    > > scanf() at all for interactive input; when data comes from
    > > an "uncontrolled" source, I prefer to read an entire line
    > > at a time with fgets() or something similar, and then pick
    > > the line apart without further I/O. fgets() plus sscanf()
    > > makes a pretty good pairing, combining the apparent ease of
    > > plain scanf() with a more predictable I/O behavior.
    > >

    > Eric
    > Thanks for your response - that was nicely explained and useful. I would
    > have googled for the solution but to be honest didn't really know what
    > to put in the search string over and above any generality (like scanf())
    > that would have generated x number of hits. I will look at the FAQ you
    > mention and see what I can come up with. I've never used fgets() before,
    > so that will be a useful technique to examine.
    >
    > Much obliged.
    >
    > - Andy
    >


    You could use a 'default' case in the switch to get rid of printing the menu
    twice.

    something like this....

    default:
    scanf("%c", &x);
    continue;

    Thanks,
    Praveen Kumar
     
    sahukar praveen, Nov 7, 2003
    #4
  5. On Fri, 07 Nov 2003 14:58:52 +0530, sahukar praveen wrote:

    > You could use a 'default' case in the switch to get rid of printing the menu
    > twice.
    >
    > something like this....
    >
    > default:
    > scanf("%c", &x);
    > continue;


    What if the user types 'h' 'e' 'l' 'l' 'o' to the program?
    How many menus would he see then?

    It takes more than your suggestion to solve the real problem.

    -Sheldon
     
    Sheldon Simms, Nov 7, 2003
    #5
  6. On Fri, 07 Nov 2003 14:58:52 +0530, sahukar praveen wrote:

    > You could use a 'default' case in the switch to get rid of printing the menu
    > twice.
    >
    > something like this....
    >
    > default:
    > scanf("%c", &x);
    > continue;


    Let me respond again, since the first response was bogus, although the
    basic idea I was trying to get across is the same as what I want to say
    now.

    The problem with this suggestion is that it is designed to eliminate
    the symptom without actually fixing the problem.

    If you add this code to the sample program given, the extra menu isn't
    printed, but the behavior of the program is still not what one would
    expect.
     
    Sheldon Simms, Nov 7, 2003
    #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. Tat
    Replies:
    0
    Views:
    366
  2. Niv
    Replies:
    7
    Views:
    4,927
    OutputLogic
    May 22, 2009
  3. -intl.com
    Replies:
    1
    Views:
    371
    Martin Gregorie
    Oct 22, 2006
  4. Kiuhnm

    twice(twice(x))

    Kiuhnm, Apr 1, 2006, in forum: C++
    Replies:
    2
    Views:
    395
    Kiuhnm
    Apr 1, 2006
  5. Kaye Ng

    ruby calc.rb or just calc.rb

    Kaye Ng, Jul 26, 2010, in forum: Ruby
    Replies:
    7
    Views:
    407
    Kaye Ng
    Jul 28, 2010
Loading...

Share This Page