валидация ввода cmdline input argv [] содержит все целые - PullRequest
5 голосов
/ 14 февраля 2011

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

Мне предложили использовать метод strtol (), однако я знаю, что если целое число недопустимо, оно возвращает 0, но мне нужно вернутьсообщение об ошибке вместо 0, потому что 0 допустимо.Есть ли другой метод, который я могу использовать для проверки ввода?

Ответы [ 4 ]

3 голосов
/ 14 февраля 2011

strtol не имеют только своего возвращаемого значения, чтобы сигнализировать об ошибке в преобразовании, у него также есть второй параметр (endptr на моей man-странице); если вы передадите ему указатель на char *, он сохранит там позицию первого символа, который он не смог преобразовать, или оставит его в покое, если ничего не удалось преобразовать. Таким образом, у вас есть следующие случаи:

char * endptr=NULL;
int out=strtol(yourstring, &endptr, 10);
if(endptr==NULL)
{
    /* the whole string is garbage - no numbers extracted */
}
else if(*endptr==0)
{
    /* the whole string was a number - yay! */
}
else
{
    /* strtol extracted a number from the string, but stopped at some invalid character
       that you can check by looking at the value of endptr */
}

Кроме того, вы также можете проверить значение, которое strtol устанавливает errno в случае проблем; EINVAL используется, если ничего не может быть извлечено, другие значения можно увидеть на справочной странице strtol.

Вы также можете использовать sscanf и проверить его возвращаемое значение, чтобы быстро увидеть, может ли строка быть или не может быть преобразована в int (или в то, что вы задали в строке формата).

1 голос
/ 14 февраля 2011

Если strtol() обнаружит ошибку, для errno будет установлено значение EINVAL. Из справочной страницы :

Возвращаемое значение

Функция strtol() возвращает результат преобразования, если только значение не будет уменьшено или переполнено. ... В обоих случаях errno устанавливается на ERANGE. ...

Ошибка

EINVAL ... Данная база содержит неподдерживаемое значение. ...

Реализация также может установить errno на EINVAL в случае, если преобразование не было выполнено (цифры не видны, а 0 возвращено).

0 голосов
/ 14 февраля 2011

Для правильного использования strtol необходимо сбросить errno перед вызовом. И если вы пишете код, который хотите повторно использовать в других проектах, этот код не должен иметь непреднамеренных побочных эффектов. Таким образом, есть два варианта: простой, который, вероятно, достаточно хорош в вашем случае, и сложный, который будет приемлем в библиотеке многократно используемого кода.

#include <errno.h>
#include <stdbool.h>
#include <stdlib.h>

/* the simple variant, with the side-effect of changing errno */
static bool is_long_1(const char *s)
{
  char *end;

  errno = 0;
  strtol(s, &end, 10);
  return errno == 0 && *end == '\0';
}

/* the complex variant, without side-effects */
static bool is_long_2(const char *s)
{
  char *end;
  int saved_errno = errno;
  errno = 0;

  strtol(s, &end, 10);
  bool succeeded = errno == 0 && *end == '\0';
  errno = saved_errno;
  return succeeded;
}

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

0 голосов
/ 14 февраля 2011

Аргументы командной строки являются строками, почему бы не использовать isdigit(3)?

...