Повторите подсказку программы - PullRequest
0 голосов
/ 06 апреля 2019

В настоящее время проблема связана с подсказкой Evaluate another interval (Y/N)?.Допустим, я запускаю программу 4 раза;чтобы завершить его, мне нужно набрать N 4 раза.

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;
}

Я ожидаю, что, независимо от того, какой прогон программы, на которой я нахожусь, он закроется, когда я наберу один N.

Ответы [ 2 ]

1 голос
/ 06 апреля 2019

Есть много способов достичь желаемого, но рекурсивный вызов main не очень хорошая идея.

Довольно простой способ изменить программу - добавить дополнительный уровень while(1).Что-то вроде:

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
}

Другой способ (более простой способ, IMO) - поместить код, в котором вы просите пользователя, в функцию, которую вы вызываете из main.Как:

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;
}

Кстати: взгляните на getchar вместо использования scanf

0 голосов
/ 06 апреля 2019

В вашей программе несколько проблем:

  • Вы проверяете возвращаемое значение scanf() при чтении ответа пользователя на подсказки и корректно очищаете ожидающий ввод, но не обрабатываете потенциальный конец файла, что приводит к бесконечным циклам.
  • c должен быть определен как int для учета всех значений, возвращаемых getchar(): 256 значений типа unsigned char и специального значения EOF.
  • Вы можете main() рекурсивно повторить действие программы, требующее нескольких N ответов. Вместо этого вы должны добавить внешний цикл и выйти из него при N ответе или конце файла.

Вот модифицированная версия:

#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;
        }
    }             
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...