как заставить программу принимать только положительные целочисленные значения в c - PullRequest
0 голосов
/ 12 октября 2018

написание программы, которая будет находить min, max, avg значений, введенных пользователем.Возникли проблемы при записи чего-либо, что проверит, чтобы убедиться, что введены только положительные целые числа, и выдает сообщение об ошибке.Вот мое утверждение for, которое до сих пор читает входные данные:

  for (int value = 0; value <= numofvals; ++value) {
      printf("Value %d: %f\n", value, val_input);
      scanf("%f", &val_input);
  }

учтите, я изучал код около 3 недель и только что познакомился с циклами на этой неделе, так что мое понимание в лучшем случае зачаточно!

Ответы [ 3 ]

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

Во-первых, не используйте scanf.Если stdin не соответствует ожидаемому, он оставит его в буфере и просто перечитает тот же неправильный ввод.Это очень неприятно для отладки.

const int max_values = 10;

for (int i = 0; i <= max_values; i++) {
    int value;
    if( scanf("%d", &value) == 1 ) {
        printf("Got %d\n", value);
    }
    else {
        fprintf(stderr, "I don't recognize that as a number.\n");
    }
}

Смотрите, что происходит, когда вы кормите его чем-то, что не является числом.Он просто пытается снова и снова читать плохую строку.

$ ./test
1
Got 1
2
Got 2
3
Got 3
foo
I don't recognize that as a number.
I don't recognize that as a number.
I don't recognize that as a number.
I don't recognize that as a number.
I don't recognize that as a number.
I don't recognize that as a number.
I don't recognize that as a number.
I don't recognize that as a number.

Вместо этого используйте fgets, чтобы надежно прочитать всю строку, и sscanf, чтобы проанализировать ее.%f для поплавков, десятичных чисел.Используйте %d для распознавания только целых чисел.Затем проверьте, является ли оно положительным.

#include <stdio.h>

int main() {
    const size_t max_values = 10;
    int values[max_values];
    char buf[1024];

    size_t i = 0;
    while(
        // Keep reading until we have enough values.
        (i < max_values) &&
        // Read the line, but stop if there's no more input.
        (fgets(buf, sizeof(buf), stdin) != NULL)
    ) {
        int value;

        // Parse the line as an integer.
        // If it doesn't parse, tell the user and skip to the next line.
        if( sscanf(buf, "%d", &value) != 1 ) {
            fprintf(stderr, "I don't recognize that as a number.\n");
            continue;
        }

        // Check if it's a positive integer.
        // If it isn't, tell the user and skip to the next line.
        if( value < 0 ) {
            fprintf(stderr, "Only positive integers, please.\n");
            continue;
        }

        // We got this far, it must be a positive integer!
        // Assign it and increment our position in the array.
        values[i] = value;
        i++;
    }

    // Print the array.
    for( i = 0; i < max_values; i++ ) {
        printf("%d\n", values[i]);
    }
}

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

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

Что-то простое, как это может работать для вас:

int n;
int ret;

for (;;) {
    ret = scanf("%d", &n);

    if (ret == EOF)
        break;

    if (ret != 1) {
        puts("Not an integer");
        for (;;)
            if (getchar() == '\n')
                break;
        continue;
    }

    if (n < 0) {
        puts("Not a positive integer");
        continue;
    }

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

    /* Do your min/max/avg calculation */
}

/* Print your results here */

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

Чтобы выйти из цикла, вам нужно передать EOF (обычно Ctrl + D в Linux /MacOS-терминалы, Ctrl + Z в Windows).

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

Простое и портативное решение

#include <limits.h>
#include <stdio.h>
int get_positive_number() {
  char buff[1024];
  int value, ch;
  while (1) {
    printf("Enter positive number: ");
    if (fgets(buff, 1023, stdin) == NULL) {
      printf("Incorrect Input\n");
      // Portable way to empty input buffer
      while ((ch = getchar()) != '\n' && ch != EOF)
        ;
      continue;
    }
    if (sscanf(buff, "%d", &value) != 1 || value < 0) {
      printf("Please enter a valid input\n");
    } else {
      break;
    }
  }
  return value;
}
void solution() {
  // Handling malformed input
  // Memory Efficient (without using array to store values)
  int n;
  int min = INT_MAX;
  int max = INT_MIN;
  double avg = 0;
  printf("Enter number of elements: ");
  scanf("%d", &n);
  getc(stdin);
  int value;
  for (int i = 0; i < n; i++) {
    value = get_positive_number();
    if (value > 0) {
      if (min > value) {
        min = value;
      }
      if (max < value) {
        max = value;
      }
      avg += value;
    }
  }
  avg = avg / n;
  printf("Min = %d\nMax = %d\nAverage = %lf\n", min, max, avg);
}
int main() {
  solution();
  return 0;
}
  • Выход:

Enter number of elements: 3
Enter positive number: 1
Enter positive number: 2
Enter positive number: a
Please enter a valid input
Enter positive number: -1
Please enter a valid input
Enter positive number: 1
Min = 1
Max = 2
Average = 1.333333
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...