Bill Karver
Bill Karver

Reputation: 37

Repeat the Program Prompt

The current problem is with the Evaluate another interval (Y/N)? prompt. Let's say I run the program 4 times; in order to end it, it requires me to type N 4 times.

int main() {
    int trap, test;
    double low, hi;
    char repeat, c;

    //Gather End Points
    do {
        printf("Enter endpoints of interval to be integrated (low hi): ");
        test = scanf("%lf %lf", &low, &hi);

        if (test != 2) {
            printf("Error: Improperly formatted input\n");
            while((c = getchar()) != '\n' && c != EOF);  //Discard extra characters
        } else       
        if (low > hi)
            printf("Error: low must be < hi\n");

    } while ((test != 2 || low > hi));

    //Gather amount of triangles
    do {         
        printf("Enter number of trapezoids to be used: ");
        test = scanf("%d", &trap);

        if (test != 1) {
            printf("Error: Improperly formated input\n");
            while((c = getchar()) != '\n' && c != EOF); //Discard extra characters
        } else
        if (trap < 1)
            printf("Error: numT must be >= 1\n");

    } while ((trap < 1 || test != 1));

    //Output integrate
    printf("Using %d trapezoids, integral between %lf and %lf is %lf",
           trap, low, hi, integrate(low, hi, trap));   

    //Prompt user for another time
    while (1) {
        printf("\nEvaluate another interval (Y/N)? ");
        scanf(" %c", &repeat);

        switch (repeat) {
          case 'Y':
            main();
          case 'y':
            main();
          case 'N':
            return 0;
          case 'n':
            return 0;
          default:
            printf("Error: must enter Y or N");
        }
    }             
    return 0;
}

I expect it so that no matter what run of the program I'm on it will close when I type one N.

Upvotes: 0

Views: 109

Answers (2)

chqrlie
chqrlie

Reputation: 144655

There are multiple problems in your program:

  • You test the return value of scanf() when reading the user's answer to the prompts, and you clear the pending input correctly, but you do not handle the potential end of file, leading to endless loops.
  • c must be defined as int to accommodate for all values returned by getchar(): 256 values of type unsigned char and the special value EOF.
  • You can main() recursively to repeat the program's action requiring multiple N answers. You should instead add an outer loop and exit from it upon a N answer or an end of file condition.

Here is a modified version:

#include <stdio.h>

double integrate(double low, double hi, int trap) {
    ...
}

int flush_line(void) {
    // Consume the pending input and return `'\n`` or `EOF`
    int c;
    while ((c = getchar()) != EOF && c != '\n')
        continue;
    return c;
}

int main() {
    // Main program loop
    for (;;) {
        int trap, test;
        double low, hi;
        char repeat;

        //Gather End Points
        for (;;) {
            printf("Enter endpoints of interval to be integrated (low hi): ");
            test = scanf("%lf %lf", &low, &hi);
            if (test == EOF)
                return 1;
            if (test != 2) {
                printf("Error: Improperly formatted input\n");
                if (flush_line() == EOF)
                    return 1;
                continue;  // ask again
            }
            if (low > hi) {
                printf("Error: low must be < hi\n");
                continue;
            }
            break;  // input is valid
        }

        //Gather amount of triangles
        for (;;) {         
            printf("Enter number of trapezoids to be used: ");
            test = scanf("%d", &trap);
            if (test == EOF)
                return 1;
            if (test != 1) {
                printf("Error: Improperly formated input\n");
                if (flush_line() == EOF)
                    return 1;
                continue;
            }
            if (trap < 1) {
                printf("Error: numT must be >= 1\n");
                continue;
            }
            break;
        }

        //Output integrate
        printf("Using %d trapezoids, integral between %lf and %lf is %lf\n",
               trap, low, hi, integrate(low, hi, trap));

        //Prompt user for another time
        for (;;) {
            printf("\nEvaluate another interval (Y/N)? ");
            if (scanf(" %c", &repeat) != 1)
                return 1;  // unexpected end of file

            switch (repeat) {
              case 'Y':
              case 'y':
                break;
              case 'N':
              case 'n':
                return 0;
              default:
                printf("Error: must enter Y or N\n");
                if (flush_line() == EOF)
                    return 1;
                continue;
            }
            break;
        }
    }             
}

Upvotes: 0

4386427
4386427

Reputation: 44264

There are many ways to achieve what you want but calling main recursively is not a good idea.

A pretty simple way to change your program is to add an additional while(1) level. Something like:

int main(void) 
{
    char repeat;
    while(1){       // Outer while to keep the program running

        printf("running program\n");

        // Put your program here

        printf("program done\n");

        repeat = '?';
        while(repeat != 'y' && repeat != 'Y'){  // Repeat until input is 'Y' or 'y'
            printf("\nEvaluate another interval (Y/N)? ");
            scanf(" %c", &repeat);

            switch (repeat){
                case 'Y':
                case 'y':
                    break;
                case 'N':
                case 'n':
                    return 0;   // Stop if input is 'n' or 'N'
               default:
                   printf("Error: must enter Y or N");
            }    
        }
    }

    return 0;  // This will never be reached
}

Another way (a simpler way, IMO) is to put the code where you ask the user into a function that you call from main. Like:

int continueProg()
{
    char repeat = '?';
    while(1){
        printf("\nEvaluate another interval (Y/N)? ");
        scanf(" %c", &repeat);

        switch (repeat){
            case 'Y':
            case 'y':
                return 1;;
            case 'N':
            case 'n':
                return 0;
            default:
                printf("Error: must enter Y or N");
        }    
    }
}

int main(void) 
{
    do {

        printf("running program\n");

        // Put your program here

        printf("program done\n");

    } while(continueProg());

    return 0;
}

BTW: Take a look at getchar instead of using scanf

Upvotes: 1

Related Questions