Как написать собственную функцию isnumber()?

Я новичок в C и думаю, как самому написать эту функцию. Я беру параметр из командной строки, поэтому он хранится в массиве argv, и я хочу решить, является ли он числом или нет. Как это сделать проще всего?

Спасибо

#include <stdio.h>

int isNumber(int *param)
{   
    if (*param > 0 && *param < 128)
        return 1;
    return 0;
} 

int main(int argc, char *argv[])
{
    if (argc == 2)
        isNumber(argv[1]);
    else printf("Not enought parameters.");

    return 0;
}

person John Smith    schedule 06.10.2013    source источник
comment
Что заставляет вас думать, что argv[1] превращается в int?   -  person P0W    schedule 06.10.2013
comment
Ваш код не будет компилироваться без ошибок. Так как argv[1] — это char*, а isNumber хочет int (и имя у него очень неудачное: каждое int param является числом!)   -  person Basile Starynkevitch    schedule 06.10.2013


Ответы (4)


Прочтите о strtol(3). Вы можете использовать его как

bool isnumber(const char*s) {
   char* e = NULL;
   (void) strtol(s, &e, 0);
   return e != NULL && *e == (char)0;
}

но это не очень эффективно (например, для строки с миллионом цифр), поскольку будет выполнено бесполезное преобразование.

Но на самом деле вас часто волнует значение этого числа, поэтому вы должны вызывать strtol при обработке аргументов вашей программы (из аргумента argv в main) и заботиться о результате strtol, который является фактическим значением числа.

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

E.g.

int main (int argc, char**argv) {
   long num = 0;
   char* endp = NULL;
   if (argc < 2) 
     { fprintf(stderr, "missing program argument\n");
       exit (EXIT_FAILURE); }; 
   num = strtol (argv[1], endp);
   if (endp == NULL || *endp != (char)0)
     { fprintf(stderr, "program argument %s is bad number\n", argv[1]);
       exit (EXIT_FAILURE); }; 
   if (num<0 || num>=128)
     { fprintf(stderr, "number %ld is out of bounds.\n", num);
       exit(EXIT_FAILURE); };
   do_something_with_number (num);
   exit (EXIT_SUCCESS);
 } 
person Basile Starynkevitch    schedule 06.10.2013
comment
Я знаю функцию strtol. На самом деле я хотел сделать это без него. И максимальное число будет 127. - person John Smith; 06.10.2013
comment
Затем используйте strtol и проверьте также, что результатом является <128 (и, возможно, >=0), и проверьте указатель конца. Кстати, 127 может быть записано как 00000177 (восьмеричное) или 0x000000000000000000000000000000000000000000000000000000000007F (шестнадцатеричное) каким-то странным пользователем. - person Basile Starynkevitch; 06.10.2013

Как насчет

#define MYISNUM(x) ((x) >= '0' && (x) <= '9')
person Ed Heal    schedule 06.10.2013
comment
Лучше использовать isdigit из <ctype.h> - person Basile Starynkevitch; 06.10.2013

Как насчет того, чтобы попробовать так:

#include <ctype.h>

if(isdigit(input))
{
  return true;
}
else
{
  return false;
}

ИЛИ проще, как прокомментировал H2CO3:

 #define isnumber isdigit

OR

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int main () {

  //some code
  theChar = atoi(string[i]);
  if (isdigit(theChar)) {
    return true;
  }
  return 0;
}
person Rahul Tripathi    schedule 06.10.2013
comment
Это записывается проще как #define isnumber isdigit - person ; 06.10.2013
comment
@H2CO3:- Да, это правда. Я просто подумал написать так. Это неправильно? :( - person Rahul Tripathi; 06.10.2013
comment
Это не неправильно, просто лишнее, и ИМХО это не очень помогает, так как у OP есть строка, а не один символ (не то чтобы он не мог понять это сам, но все же.) - person ; 06.10.2013
comment
@H2CO3:- Понятно! Обновил мой ответ более простой версией, как было предложено. Спасибо - person Rahul Tripathi; 06.10.2013
comment
Да видел, отлично. - person ; 06.10.2013

Я не уверен, хотите ли вы проверить, является ли это числом или цифрой, а argv[1] имеет тип char *, а не int, поэтому вы должны сделать что-то вроде этого:

bool isDigit(char *param)
{   
    return (*param >= `0` && *param <= `9`)
}

bool isNumber(char *param)
{   
    while (param)
    {
        if (!isDigit(param))
            return false;
       param++;
    }
    return true;
} 
person Roee Gavirel    schedule 06.10.2013