Я пытаюсь написать простую программу для решения практической задачи, написанную ниже:

(Калькулятор комиссионных с продаж) Одна крупная химическая компания платит своим продавцам на комиссионной основе. Продавцы получают 200 долларов в неделю плюс 9% их валовых продаж за эту неделю. Например, продавец, который продает химикатов на 5000 долларов в неделю, получает 200 долларов плюс 9% от 5000 долларов, или в общей сложности 650 долларов. Разработайте программу, которая будет вводить данные о валовых продажах каждого продавца за прошлую неделю, а также рассчитывать и отображать доходы этого продавца. Обрабатывайте данные по одному продавцу за раз.

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

Мой код:

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

int main(void){
    float sales = 0;
    float salary = 0;

    while (sales != -1)
    {
        printf("Enter sales in dollars (-1 to end): ");
        scanf("%f", &sales);

        while ((sales != -1) && !(sales >= 0))
        {
            puts("Input error, please try again");
            fflush(stdin);
            printf("Enter sales in dollars (-1 to end): ");
            scanf("%f", &sales);
        }

        if (sales != -1)
        {
            salary = 200 + (0.09 * sales);

            printf("Salary is: $%.2f\n", salary);
        }
    }

    return 0;
}

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

Код другой программы:

while(!(collected >= 0))
{
    fflush(stdin);
    puts("Input error, please try again.");
    printf("Enter total amount collected (-1 to quit): $");
    scanf("%f", &collected);
}

Будем очень признательны за объяснение!

1
lowkeyhuman 12 Окт 2020 в 13:01

1 ответ

Лучший ответ

scanf("%f", ...) никогда не примет ничего, кроме правильно отформатированного числа, поэтому, если вы введете символ, все ваши вызовы scanf() будут просто видеть, что есть символ, который нужно использовать, но спецификатор формата не позволяет это, и они ничего не прочитают и вернут 0. Это, плюс ваш while, вызовет бесконечный цикл, если будет введено что-нибудь, что не является допустимым числом.

Вы должны либо прочитать все до конца строки, либо пропустить ненужные символы, когда scanf возвращает 0 (что означает, что он не смог правильно прочитать какое-либо значение). Также проверьте, возвращает ли scanf EOF, что означает, что либо произошла ошибка, либо был достигнут конец файла.

В любом случае fflush(stdin) является неопределенное поведение, никогда не делайте этого!

Правильный способ сделать это:

#include <stdio.h>

int main(void) {
    float sales = 0;
    float salary;
    int res;

    do {
        printf("Enter sales in dollars (-1 to end): ");
        fflush(stdout);

        res = scanf("%f", &sales);

        if (res == EOF) {
            // Something bad happened.

            if (feof(stdin))
                fputs("End of input reached.\n", stderr);
            else
                perror("Error reading input");

            return 1;
        }

        if (sales != -1 && sales < 0) {
            // Perhaps it would be a better idea to say "invalid value" here?
            puts("Input error, please try again.");
            res = 0;
        }
        
        // Either the value was read correctly (res = 1) or it wasn't (res = 0).
        // In any case, consume the rest of the line.
        scanf("%*[^\n]");

    } while (res != 1 && sales != -1.0);

    if (sales != -1.0) {
        salary = 200 + (0.09 * sales);
        printf("Salary is: $%.2f\n", salary);
    }

    return 0;
}
2
Marco Bonelli 12 Окт 2020 в 11:48