Как анализировать аргументы командной строки целых чисел в C?

Я хотел бы, чтобы пользователь передал два параметра или оставил их пустыми. Например:

./program 50 50

или

./program

Когда я попытался использовать int main(int argc, char *argv[]), первое, что я сделал, это изменить char *argv[] на int *argv[], но это не сработало. Я хочу, чтобы пользователь просто вводил два целых числа от 0 до 100. Поэтому, если это не два целых числа, тогда это должно дать ошибку.

Я как бы думал о том, чтобы выдать ошибку с типами (как я использовал для программирования на С#), но независимо от того, что я вхожу, argv [1] будет всегда "char".

Итак, что я сделал,

for (int i = 0; i <= 100; i++) {
    //printf("%d", i);
    if (argv[1] == i) {
        argcheck++;
        printf("1st one %d\n", i);
    }
    else if (argv[2] == i) {
        argcheck++;
        printf("2nd one %d\n", i);
    }

Это не работает. Кроме того, он дает предупреждение при компиляции, но если я, например, меняю argv на atoi(argv[1]), то он дает ошибку с ошибкой сегментации (core dumped).

Мне нужен простой способ решить эту проблему.

EDIT:

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

./program asd asd

Тогда вывод atoi(argv[1]) будет равен 0. Есть ли способ изменить это значение?

Ответы

Ответ 1

Не используйте atoi() и не используйте strtol(). atoi() не проверяет ошибки (как вы выяснили!), а strtol() должен быть проверен ошибкой с использованием глобальной переменной errno, что означает, что вы должны установить errno в 0, затем вызвать strtol(), затем снова проверьте errno на наличие ошибок. Лучше использовать sscanf(), который также позволяет анализировать любой примитивный тип из строки, а не только целое число, и позволяет читать модные форматы (например, hex).

Например, чтобы разобрать целое число "1435" из строки:

if (sscanf (argv[1], "%i", &intvar) != 1) {
    fprintf(stderr, "error - not an integer");
}

Чтобы разобрать один символ "Z" из строки

if (sscanf (argv[1], "%c", &charvar)!=1) {
    fprintf(stderr, "error - not a char");
}

Чтобы проанализировать поплавок "3.1459" из строки

if (sscanf (argv[1], "%f", &floatvar)!=1) {
    fprintf(stderr, "error - not a float");
}

Чтобы проанализировать большое шестнадцатеричное целое без знака "0x332561" из строки

if (sscanf (argv[1], "%xu", &uintvar)!=1) {
    fprintf(stderr, "error - not a hex integer");
}

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

Ответ 2

Это сделает:

int main(int argc, char*argv[])
{
   long a,b;
   if (argc > 2) 
   {
      a = strtol(argv[1], NULL, 0);
      b = strtol(argv[2], NULL, 0);
      printf("%ld %ld", a,b);
   }
   return 0;
}

Ответ 3

Аргументы всегда передаются как строки, вы не можете изменить прототип main(). Операционная система и окружающие механизмы всегда передают строки и не могут понять, что вы ее изменили.

Вам нужно использовать, например. strtol(), чтобы преобразовать строки в целые числа.

Ответ 4

Вы хотите проверить,

  • Получен 0 или 2 аргумента
  • два полученных значения находятся между 0 и 100
  • полученный аргумент не является строкой. Если строка придет, sscanf вернется 0.

Ниже логика поможет вам

int main(int argc, char *argv[])
{
    int no1 = 0, no2 = 0, ret = 0;

    if ((argc != 0) && (argc != 2)) 
    {
        return 0;
    }

    if (2 == argc)
    {
        ret = sscanf(argv[1], "%d", &no1);
        if (ret != 1)return 0;
        ret = sscanf(argv[2], "%d", &no2);
        if (ret != 1)return 0;          

        if ((no1 < 0) || (no1 >100)) return 0;
        if ((no2 < 0) || (no2 >100)) return 0;          
    }

    //now do your stuff
}

Ответ 5

То, что вы сделали так невинно, - это ошибка в C. Независимо от того, вы должны принимать строки или символы в качестве своих аргументов, а затем вы можете делать с ними все, что вам нравится. Либо измените их на целое с помощью strtol, либо пусть они будут строками и проверит каждую char строки в диапазоне 48 to 57, так как это десятичные значения char 0 to 9. Лично это не очень хорошая идея и не очень хорошая практика кодирования. Лучше конвертируйте их и проверьте нужный диапазон целых чисел.

Ответ 6

Вы можете еще использовать atoi, просто проверьте, является ли аргумент первым числом;)
btw ppl скажет вам, что goto - это зло, но обычно их промывают мозги неразумным "goto is bad" , "goto is evil" , "goto - это дьявол" , которые были просто выброшены без разработки в Интернете.
Да, код spaggethi менее управляем. И goto в этом контексте - это возраст, когда он заменил функции...

    int r, n, I;
    for (I = 0; I < argc; ++I)
    {
      n = 0;
      do
        if ( !((argv + I) [n] >= '0' && (argv + I) [n] <= '9') )
        {
          err:
            fprintf(stderr,"ONLY INTEGERS 0-100 ALLOWED AS ARGUMENTS!\n");
            return 1;
        }
      while ((argv + I) [++n] != '\0')
      r = atoi(argv[I]);
      if (r > 100)
        goto err;
    }

Ответ 7

Вы не можете изменить аргументы функции main(). Поэтому вы должны просто использовать функцию atoi() для преобразования аргументов из строки в integer.

atoi() имеет свои недостатки. То же самое верно для функций strtol() или strtoul(). Эти функции возвращают значение 0, если вход в функцию не является числовым. Пользователь вводит asdf или что-то иное, кроме действительного числа. Чтобы преодолеть это, вам нужно будет разобрать строку перед передачей ее atoi() и вызвать isdigit() для каждого символа, чтобы убедиться, что пользователь имеет действительное число. После этого вы можете использовать atoi() для преобразования в целое число.

Ответ 8

#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
main(int argc,char *args[])
{
    int i,sum=0;
    for(i=0;i<=argc;i++)
    {
        printf("\n The %d argument is: %s",i,args[i]);
    }
    printf("\nTHe sum of given argumnets are:");
    for(i=1;i<argc;i++)
    {
       int n;
       n=atoi(args[i]);
       printf("\nN=%d",n);
       sum += n;
    }
    printf("\nThe sum of given numbers are %d",sum);
    return(0);

  }

проверить эту программу, я добавил другую библиотеку stdlib.h и поэтому могу преобразовать массив символов в строку, используя функцию atoi.