функция с опцией проверки ввода и повторной попытки

#c #function #pass-by-reference

#c #функция #передача по ссылке

Вопрос:

Я хочу знать, как я могу реализовать проверку ввода в функции getFloats, чтобы, если пользователь вводит нежелательный ввод (например, слово или букву вместо цифры), функция печатала сообщение и предоставляла пользователю возможность повторить попытку, и эта функция завершается и не выдаетвозможность повторной попытки ввода. Является ли более профессиональным прекратить использование scanf и начать использовать лучший метод ввода?

 #include <stdio.h>

void getFloats(float *a, float *b);

int main()
{
    float num1,num2;
    
    getFloats(amp;num1,amp;num2);
    printf("%.2f and %.2fn", num1, num2);
    
    return 0;
}

void getFloats(float *a, float *b)
{
    puts("Enter numbers:");
    scanf("%f", a);
    if ( scanf("%f", a) == 0)
    {
        puts("try again");
        scanf("%f", a);
    }
    else
    {
        scanf("%f", b);
    }
}
  

Комментарии:

1. Я никогда не использую scanf() . Я предпочитаю читать всю строку, а затем использовать семейство strtol() функций and strtof() .

2. Небезопасно использовать scanf без проверки возвращаемого значения. Смотрите эту страницу для получения дополнительной информации: руководство для начинающих по scanf ()

3. Страница в комментарии к моей ссылке выше также объясняет, когда ее целесообразно использовать scanf и когда fgets лучше.

4. @AndreasWenzel Эта статья была невероятным предложением. Спасибо

Ответ №1:

что касается;

 scanf("%f", a);
if ( scanf("%f", a) == 0)
  
  1. это вызывает scanf() дважды для одной и той же переменной
  2. лучше всего проверить наличие положительного состояния.

Вот предлагаемый код:

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

void getFloats(float *a, float *b)
{
    puts("Enter numbers:");

    if( scanf( "%f %f", a, b ) != 2 )
    {
        fprintf( stderr, "scanf failedn" );
        exit( EXIT_FAILURE );
    }
}
  

ОЧЕНЬ маловероятно, что scanf() повторный вызов устранит проблему, потому что проблема все еще будет в stdin потоке