Функция, которая запрашивает у пользователя целочисленное значение и проверяет правильность ввода - PullRequest
0 голосов
/ 16 октября 2018

В настоящее время я застрял на небольшой части задания, которое мне нужно сделать.Одно из требований присваивания:

. «Вызвать функцию, которая запрашивает у пользователя каждое из значений коэффициентов a, b и c для квадратного уравнения и возвращает введенное значение с проверкой ошибок.для правильного ввода (scanf вернул значение). "

и я не могу понять, как это сделать.Я легко могу попросить пользователя ввести данные и проверить, является ли это допустимым, но я не знаю, как превратить это в функцию.Мой текущий код:

   {
   if (isalpha(a))
   {
      printf("INPUT ERROR!\n");
      printf("Enter a value for a: ");
      scanf("%d", &a);
   }
   } //this is how I would normally check the input

   int main(void) //start of main() function definition
   {
      int a, b, c, n, D; //declares integer variables a, b, c, n, and D
      float root1, root2; //declares float variables root1 and root2

      do //do while loop starts here
      {
         printf("Enter a value for a: "); //prompts user to input integer for variable 'a'
         scanf("%d", &a); //reads an integer from the keyboard and stores in the variable 'a' 
         printf("%d\n", a); //returns value of integer that was input for variable 'a'

         printf("Enter a value for b: "); //prompts user to input integer for variable 'b'
         scanf("%d", &b); //reads an integer from the keyboard and stores in the variable 'b'
         printf("%d\n", b); //returns value of integer that was input for variable 'b'

         printf("Enter a value for c: "); //prompts user to input integer for variable 'c'
         scanf("%d", &c); //reads an integer from the keyboard and stores in the variable 'c'
         printf("%d\n", c); //returns value of integer that was input for variable 'c'
         ...}

Извините за любые ошибки форматирования, но это в основном часть программы, с которой я застрял.

У меня вопрос: как я могу объединить первую функцию со всем в цикле do / while, чтобы создать одну большую функцию, которую я могу вызвать три раза?

Я не знаю, как яЯ смог бы переключать все экземпляры a для b и c, используя функцию, так как мне никогда раньше не приходилось использовать такую ​​функцию.

Ответы [ 5 ]

0 голосов
/ 17 октября 2018

Функция, которая запрашивает у пользователя целочисленное значение и проверяет допустимый ввод

Если пользователи вводят действительный целочисленный текст только построчно, то код прост:

// Overly idealized case
fputs(prompt, stdout);
char buf[50];
fgets(buf, sizeof buf, stdin);
int i = atoi(buf);

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

Особенно язаинтересованы в обнаружении чрезмерно длинного ввода как враждебного и столь же недействительного, как разумный замысел против хакеров.Как показано ниже, небольшая причина для допустимого ввода для 32-разрядного int с более чем 20 символовЭто рациональное объяснение заслуживает более глубокого объяснения.

  • Конец файла
  • Ошибка входного потока
  • Переполнение
  • Нет начального числового теста
  • Конечный нечисловой текст
  • Чрезмерно длинная строка

Сначала строка ввода читается с fgets(), а затем с различной int проверкойтесты применяются.Если fgets() не прочитал всю строку, остальное читается.

#include <limits.h>
#include <ctype.h>

// Max number of `char` to print an `int` is about log10(int_bit_width)
// https://stackoverflow.com/a/44028031/2410359
#define LOG10_2_N 28
#define LOG10_2_D 93
#define INT_DEC_TEXT (1 /*sign*/ + (CHAR_BIT*sizeof(int)-1)*LOG10_2_N/LOG10_2_D + 1)

// Read a line and parse an integer
// Return:
//   1: Success
//   0: Failure
//   EOF: End-of-file or stream input error
int my_get_int(int *i) {
  // Make room for twice the expected need. This allows for some
  // leading/trailing spaces, leading zeros, etc.
  //           int        \n  \0
  char buf[(INT_DEC_TEXT + 1 + 1) * 2];
  if (fgets(buf, sizeof buf, stdin) == NULL) {
    *i = 0;
    return EOF; // Input is either at end-of-file or a rare input error.
  }
  int success = 1;

  char *endptr;
  errno = 0;
  long value = strtol(buf, &endptr, 10);


  // When `int` is narrower than `long`, add these tests
#if LONG_MIN < INT_MIN || LONG_MAX > INT_MAX
  if (value < INT_MIN) {
    value = INT_MIN;
    errno = ERANGE;
  } else if (value > INT_MAX) {
    value = INT_MAX;
    errno = ERANGE;
  }
#endif
  *i = (int) value;
  if (errno == ERANGE) {
    success = 0;  // Overflow
  }

  if (buf == endptr) {
    success = 0; // No conversion
  }

  // Tolerate trailing white-space
  // Proper use of `is...()` obliges a `char` get converted to `unsigned char`.
  while (isspace((unsigned char ) *endptr)) {
    endptr++;
  }

  // Check for trailing non-white-space
  if (*endptr) {
    success = 0; // Extra junk
    while (*endptr) {  // quietly get rest of buffer
      endptr++;
    }
  }

  // Was the entire line read?
  // Was the null character at the buffer end and the prior wasn't \n?
  const size_t last_index = sizeof buf / sizeof buf[0] - 1;
  if (endptr == &buf[last_index] && buf[last_index - 1] != '\n') {
    // Input is hostile as it is excessively long.
    success = 0;  // Line too long
    // Consume text up to end-of-line
    int ch;
    while ((ch = fgetc(stdin)) != '\n' && ch != EOF) {
      ;
    }
  }

  return success;
}

Пример использования

     puts("Enter a value for a: ", stdout);
     fflush(stdout);  // Insure output is seen before input.
     int a;
     if (my_get_int(&a) == 1) {
       printf("a:%d\n", a); 
     }
0 голосов
/ 16 октября 2018

scanf() уже обрабатывает ввод для вас в соответствии со спецификатором формата (%d), поэтому вам просто нужно понять, как работает scanf, и использовать его для проверки и построения вашей функции:)

Когда вы пишете scanf("%d", &a);, программа ожидает, что вы напишите целое число из-за спецификатора %d, и, если целое число читается, программа записывает его в переменную a.

Но функция scanfтакже имеет возвращаемое значение, т. е. вы можете сделать check = scanf("%d", &a);, а check будет иметь значение 0 или 1 в этом случае.Это потому, что возвращаемое значение записывает, сколько значений было успешно прочитано.Если вы ввели dsfugnodg, то числа нет, поэтому он вернул бы 0. Если вы ввели 659 32, он успешно прочитал бы 1-е значение и вернул 1.

Ваша функция будет выглядеть примерно так:

#include <stdio.h>

int getAndPrint(char label)
{
    int n = 0, val = 0;
    do {
        printf("Enter a value for %c: ", label);
        n = scanf("%d", &val);
        if (n == 0) {
            printf("Error, invalid value entered.\n");
            /* Consume whatever character leads the wrong input 
             * to prevent an infinite loop. See: 
             * https://stackoverflow.com/questions/1669821/scanf-skips-every-other-while-loop-in-c */
            getchar();
        }
    } while (n == 0);
    printf("%c = %d\n", label, val);
    return val;
}

int main()
{
    int a, b, c;
    a = getAndPrint('a');
    b = getAndPrint('b');
    c = getAndPrint('c');
    printf("a=%d, b=%d, c=%d\n", a, b, c);
}

См. Также: Scanf пропускает все остальные циклы while в C

0 голосов
/ 16 октября 2018

Я думаю, что вам нужен следующий код:

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>  // for isalpha

void InputAndCheck(int * pValue, const char * pName)
{
    do
    {
        printf("Enter a value for %s: ", pName);
        scanf("%d", pValue);
        if (isalpha(*pValue))
        {
            printf("INPUT ERROR!\n");
            continue;
        }
        else
        {
            break;
        }
    } while (1);

    // clear the input buffer
    fflush(stdin);
    return;
}

int main()
{
    int a, b, c;
    InputAndCheck(&a, "a");
    InputAndCheck(&b, "b");
    InputAndCheck(&c, "c");
    printf("a=%d;b=%d;c=%d;\r\n",a,b,c);
    return 0;
}
0 голосов
/ 16 октября 2018

У меня вопрос: как я могу объединить первую функцию со всем в цикле do / while, чтобы сделать одну большую функцию, которую я могу вызвать три раза?

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

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

int input(char *prompt)
{   // prompts user to input integer
    // reads an integer from standard input and returns it
    int a, s;   // leave it to scanf to check the input:
    while (printf("%s", prompt), fflush(stdout), s = scanf("%d", &a), !s)
    {
        printf("INPUT ERROR!\n");
        do s = getchar(); while (s != '\n' && s != EOF);    // consume bad input
    }
    if (s == EOF) puts(""), exit(0);    // no more input
    return a;
}

In main()тогда вы можете просто сделать

     a = input("Enter a value for a: ");
     b = input("Enter a value for b: ");
     c = input("Enter a value for c: ");

(без цикла).

0 голосов
/ 16 октября 2018

То, что вы ищете, это введение в функции.Вот один из них: https://www.tutorialspoint.com/cprogramming/c_functions.htm

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

Функции позволят вам выполнить некоторый код в разных контекстах нади снова, просто меняя контекст (параметры).

Это объявляется так:

int add(int first, int second){
    //here we can use first and second
    printf("first: %d\n", first);
    printf("second: %d\n", second);

    //and eventually return a value
    return first+second;

}

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

printf("1+2 = %d\n", add(1, 2));
-->3
printf("2+2 = %d\n", add(2, 2));
-->4

Пример решения вашей задачи:

//this will handle validation
int validateInput(int input){
    if(isalpha(input)){
        printf("INPUT ERROR!\n");
        return 0;
    }
    return 1;
}

//this will prompt the user and return input only if the input is valid
int askForCoefficient(unsigned char coefficientName){
    int valid = 0;
    int value = 0;
    while(!valid){
        printf("Enter a value for %c: ", coefficientName);
        value = scanf("%d", &value);
        valid = validateInput(value);

    }

    printf("%d\n", value);

    return value;

}
...