2015-05-20 2 views
5

Я пытаюсь создать приложение командной строки в C++, и я хочу убедиться, что этот ввод является целым числом после определенного аргумента команды.Как проверить, является ли argv [count] целое число

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

while (count < argc){ 
    if (strcmp("-p", argv[count]) == 0){ 
     has_p = true; //Boolean 
     pid = atoi(argv[count + 1]); 
     if (pid == 0 && argv[count + 1] != "0"){ 
      err = 1; 
      cout << "pid argument is not a valid input" << endl; 
      pid = -1; 
     } 
     count++; 
    } 
... 
} 

Теперь этот код правильно перехватывает ошибку в этом входы:

  • -p 1777
  • -p SSS
  • -p sss17
  • -p [пробел] -U

, но с ошибкой при этом формате ввода

  • -p 17sss

Я попытался исправить это, пытаясь сравнить его с помощью Sprintf. К сожалению, поставка sprintf указателем массива char выводит только 1 символ в buffer2.

while (count < argc){ 
    if (strcmp("-p", argv[count]) == 0){ 
     has_p = true; //Boolean 
     pid = atoi(argv[count + 1]); 
     sprintf(buffer, "%d", pid); 
     sprintf(buffer2, "%d", *argv[count + 1]); 
     if (pid == 0 && argv[count + 1] != "0" || (buffer != buffer2)){ 
      err = 1; 
      cout << "pid argument is not a valid input" << endl; 
      pid = -1; 
     } 
     count++; 
    } 
... 
} 

Есть ли способ заставить sprintf читать весь массив символов? Если нет, есть ли лучшее решение для этого, кроме прокрутки указателя до тех пор, пока я не нажму «\ 0»

+8

Выберите язык. Вы говорите C++, но вы используете идиомы C, и вопрос отмечен обоими. –

+1

['isdigit'] (http://www.cplusplus.com/reference/cctype/isdigit/) – 101010

+0

Используйте' strcmp' для сравнения двух строк, а не '! ='.Вы можете использовать 'if (isdigit (argv [count])), чтобы проверить, является ли аргумент цифрой. –

ответ

13

atoi() не может делать то, что вы хотите. Для этого вам нужно использовать strtol(). Он значительно улучшил возможности проверки ошибок.

Подпись:

long int strtol(const char *nptr, char **endptr, int base); 

Эта функция возвращает преобразованное целое число как длинное значение INT, иначе нулевое значение возвращается. После преобразования вы можете проверить содержимое endptr и принять решение об этом.

+1

На стороне примечание: 'endptr' будет установлено, чтобы указывать на первый символ после номера, поэтому, если число является допустимым целым числом, оно должно указывать на нуль-терминатор, который заканчивает строку. Другими словами, чтобы проверить, выполнено ли преобразование, выполните 'if (* endptr == 0)' – szczurcio

+0

, вы можете использовать возвращаемое значение функций для принятия решения. – ANjaNA

+2

@ANjaNA - Нет, вы не можете использовать возвращаемое значение, чтобы определить, завершилось ли преобразование, потому что возвращаемое значение при неудачном преобразовании также является возможным результатом успешного преобразования. Вы ** должны ** использовать значение 'endptr'. –

0

Вы также можете использовать альтернативы C++ 11, которые реализованы в терминах strtol (см. stol).

+0

Это не заслуживает downvotes, поскольку он был опубликован, в то время как вопрос был также отмечен C++ .... –

3

Следующая является удобным один вкладыш ...

sscanf(argv[count + 1], "%d%*c", &n) == 1 

... что будет оценивать справедливо, если это можно было прочитать в int n и не было трейлинг характер впоследствии. «*» В %*c подавляет назначение, поэтому нет необходимости передавать указатель на манекен char. См. scanf docs here.

+0

Я пробовал это, и это то же самое, что и выше. Работает с этими последующими входами, но не удается поймать ошибку для входа «-p 17ss» – MDuh

+0

@MDuh: как он «сбой»? - вы можете увидеть [здесь] (http://ideone.com/fiMTbo), как 'sscanf' с этим текстом возвращает' 0' ... в соответствии с вышеприведенным тестом '== 1', что означает, что он поймал ошибку , Это когда он возвращает ровно 1, что вход действителен, а 'n' будет установлен на его числовое значение. –

+0

Чтобы быть более явным, для вашего конкретного случая использования вы хотите 'if (sscanf (argv [count + 1],"% d% * c ", & pid)! = 1) {err = 1; cout << "аргумент pid недействительный ввод" << endl; pid = -1; } 'и т. д. –

1

В C вы можете просто пройти через символ * и проверить, есть ли только цифры.

char c = '0'; 
int i = 0; 
int err = 0 
while (c != '\0'){ 
    if (arg[i] < 47 || arg[i] > 57){ 
     err = 1; 
     break; 
    } 
Смежные вопросы