обработка ошибок с пользовательским вводом, пока ввод не будет правильным - PullRequest
0 голосов
/ 04 ноября 2018

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

Затем пользователь должен ввести число для триплета. Продолжение отлично работает здесь. Но для второго триплета, если пользователь не вводит целое число (например, он вводит 2x), он возвращается к началу цикла while, который, пожалуйста, введите первое число триплета. Как я могу отредактировать свой код, чтобы он не попадал в начало цикла while, а велел пользователю снова ввести второе число триплета?

#include <stdio.h>
#include <stdlib.h>
#define request "Please enter the number of triangles to check: "
#define triplet1 "Please enter the first number of the triplet: "
#define triplet2 "Please enter the second number of the triplet: "
#define Error "[ERR] Invalid number of triangles.\n "
#define Error2 "[ERR] Invalid number for the triplet.\n"
#define UCHAR_MAX 20

int main ()
{

  int triangles = 0;
  char *end;

  for (;;)
    {
      printf ("%s", request);
      char buffer[30];
      fgets (buffer, sizeof (buffer), stdin);
      triangles = strtol (buffer, &end, 10);
      if (*end != '\n' || triangles < 1 || triangles > UCHAR_MAX)
    {
      printf ("%s", Error);

      continue;
    }
      break;
    }

  float triplet[3] = { 0.0, 0.0, 0.0 };
  int i = 0;
  while (i < triangles)
    {
      float tmp = 0.0;
      printf ("%s\n", triplet1);
      char buffer[30];
      fgets (buffer, sizeof (buffer), stdin);
      tmp = strtol (buffer, &end, 10);
      if (*end != '\n' || tmp < 1)
    {
      printf ("%s", Error2);
      continue;

    }
      triplet[0] = tmp;
     tmp = 0.0;
      printf ("%s\n", triplet2);

      fgets (buffer, sizeof (buffer), stdin);
      tmp = strtol (buffer, &end, 10);
      if (*end != '\n' || tmp < 1)
    {
      printf ("%s", Error2);
      continue;              // goes back to the top of the while loop 

    }

      triplet[1] = tmp;


      i++;

    }

return 0;
}

Ответы [ 2 ]

0 голосов
/ 04 ноября 2018

Само определение ключевого слова continue говорит, что всякий раз, когда оно встречается внутри тела цикла, оно пропускает все оставшиеся операторы текущей итерации и запускает цикл с самого начала для следующей итерации.

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

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

label:
printf("%s\n", triplet2);
// other statements here
if(...) {
    ...
    goto label;
}

Тем не менее, это просто обходной путь, а не хорошая практика.

Кроме того, кажется, что у вас есть блок повторяющихся утверждений. Попробуйте включить их в какую-то функцию, чтобы повысить качество кода и удобство обслуживания.

0 голосов
/ 04 ноября 2018

Это ожидаемое поведение для оператора continue. для этого вам нужно реализовать внутренний цикл.

Если вы хотите принимать данные до тех пор, пока пользователь не введет правильное значение, попробуйте следующее: У меня нет компилятора c, поэтому я не могу его протестировать, но, надеюсь, он должен работать. Пожалуйста, дайте мне знать, если вы видите какие-либо проблемы.

while (i < triangles)
{
  float tmp = 0.0;
  char buffer[30];
  whiel(true){
    printf ("%s\n", triplet1);
  fgets (buffer, sizeof (buffer), stdin);
  tmp = strtol (buffer, &end, 10);
  if (*end != '\n' || tmp < 1)
    {
      printf ("%s", Error2);
      continue;
    }
    triplet[0] = tmp;
    break;
  }

 tmp = 0.0;
  while(true){
    printf ("%s\n", triplet2);
  fgets (buffer, sizeof (buffer), stdin);
  tmp = strtol (buffer, &end, 10);
  if (*end != '\n' || tmp < 1)
    {
         printf ("%s", Error2);
        continue;
    }
      triplet[1] = tmp;
      i++;
       break;
    }
  }
...