Why does my program loop without receiving any new

2019-07-18 02:15发布

问题:

I am trying to make is so that my program will start over once the answer is given. It just won't function again once I run it once. I want to make it functional to where the user doesn't have to start the program up again. Thanks!

#include <stdio.h>
#include <math.h>


int main()
{
    float firstnum, secondnum, answer;
    char function;

    printf("\nHello and welcome to my calculator!\n");                                             //Intro

    start:                                                                                         //Area to loop to when program completes

    printf("\nPlease input the function you would like to use.  These include +, -, *, /.\n");     //Asking for function input

    scanf("%c", &function);                                                                        //Receiving Function Input

    printf("\nNow please input the two variables.\n");                                             //Asking for variables

    scanf("%f", &firstnum);

    scanf("%f", &secondnum);                                                                       //Receiving Input for Variables

    if (function == '+')                                                                           //Doing calculation
    {
            answer = firstnum+secondnum;
    }
    else if (function == '-')
    {
    answer = firstnum-secondnum;
    }
    else if (function == '*')
    {
    answer = firstnum*secondnum;
    }
    else if (function == '/')
    {
    answer = firstnum/secondnum;
    }
    else
    {
            printf("Sorry that was an incorrect function.  The correct inputs are +, -, *, /.");       //If they don't follow the directions
    }

    printf("Your answer is %f \n", answer);                                                        //Answer

    goto start;                                                                                    //Loop

return 0;

}

回答1:

This is why you use loops. (And try not to use goto for this).

#include <stdio.h>
#include <math.h>


int main() {

    float firstnum, secondnum, answer;
    char function, buffer[2];

    while(1) {      

        printf("\nHello and welcome to my calculator!\n");                                             

        printf("\nPlease input the function you would like to use.  These include +, -, *, /.\n");     
        scanf("%s", &buffer);   
        function = buffer[0];
        printf("\nNow please input the two variables.\n");  
        scanf("%f", &firstnum);
        scanf("%f", &secondnum);
        if (function == '+') answer = firstnum+secondnum;
        else if (function == '-') answer = firstnum-secondnum;
        else if (function == '*') answer = firstnum*secondnum;
        else if (function == '/') answer = firstnum/secondnum;
        else printf("Sorry that was an incorrect function.  The correct inputs are +, -, *, /.");    

        printf("Your answer is %f \n", answer);                                                               
        } 

     return 0;
     }

This should go in an infinite loop, so use an input from the user to break; the loop to exit the program


Note : I have replaced the scanf %c with %s indicating an input of a string & used a buffer.

 scanf("%s",&buffer); function = buffer[0];

(Updated as per discussion in comments)



回答2:

It's the [enter] key. Your first scanf is reading the enter key you pressed to terminate the previous iteration.

So you need to add another scanf("%c", &function); or getchar(); just before the goto to eat the newline.

When reading in numbers, scanf will eat any initial whitespace; but when reading characters, it won't. It gives you the very next byte in the stream.


A better way, perhaps, would be to tell `scanf` where to expect all the newlines. This way you don't need that *weird* mystery line that doesn't appear to do anything but isn't commented (!); because that's gonna cause problems when you play with this code again months from now.
//scanf("%c\n", &function); /* read a character followed by newline DOESN'T WORK */
...
//scanf("%f\n", &secondnum); /* read a number followed by newline DOESN'T WORK */

This way, trailing newlines are consumed. Which is, I think, the more intuitive behavior (from the User side). Nope. Doesn't work. Wish it did, cause I'd look less foolish.


I'm not upset by the goto. It's nice to see an old friend. This is an appropriate use of it if ever there was one. It is exactly equivalent to the while form. So you should certainly be aware that most people will prefer to see while(1) because it tells you more about what's going on than label:. But for an infinite loop in a function smaller than a screen, why not? Have fun. No baby seals will be harmed. :)



回答3:

One "best practise" regarding scanf is to check it's return value. In regards to the return value of scanf, I suggest reading this scanf manual carefully and answering the following questions:

  1. int x = scanf("%d", &foo); What do you suppose x will be if I enter "fubar\n" as input?
  2. Where do you suppose the 'f' from "fubar\n" will go?
  3. If it remains in stdin, would you expect a second scanf("%d", &foo); to be successful?
  4. int x = scanf("%d", &foo); What do you suppose x will be if I run this code on Windows and press CTRL+Z to send EOF to stdin?
  5. Would it be safe to use foo if x is less than 1? Why not?
  6. int x = scanf("%d %d", &foo, &bar); What would you expect x to be if I enter "123 456\n" as input?
  7. Do you suppose the '\n' will still be on stdin? What value would char_variable hold following scanf("%c", &char_variable);?

EOF can be sent through stdin in Windows by CTRL+Z, and in Linux and friends by CTRL+D, in addition to using pipes and redirection to redirect input from other programs and files.

By using code like int function; for (function = getchar(); function >= 0 && isspace(function); function = getchar()); assert(function >= 0); or char function; assert(scanf("%*[ \n]%c", &function) == 1); you can discard leading whitespace before assigning to function.



标签: c scanf