如何在C中解析整数命令行参数?

时间:2012-08-23 11:59:28

标签: c parameter-passing command-line-arguments

我希望用户传递两个参数或将其留空。例如:

./program 50 50

./program

当我尝试使用int main(int argc, char *argv[])时,我做的第一件事就是将char *argv[]更改为int *argv[],但它不起作用。我想要的是用户只需要输入0到100之间的两个整数。因此,如果它不是两个整数,那么它应该给出一个错误。

我有点想用类型给出错误(就像我以前在C#上编程一样),但无论我输入什么,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]),则会出现分段错误(核心转储)错误。

我需要一种简单的方法来解决这个问题。

编辑:

所以我用atoi()修复了,它给出分段错误的原因是因为我在没有参数时尝试使用null值。所以我通过添加额外的cond来修复它。但现在的问题是,如果价值是假设

./program asd asd

然后atoi(argv[1])的输出将为0.有没有办法改变这个值?

7 个答案:

答案 0 :(得分:29)

请勿使用atoi(),不要使用strtol()atoi()没有错误检查(正如您发现的那样!)并且strtol()必须使用全局errno变量进行错误检查,这意味着您必须将errno设置为0,然后调用strtol(),然后再次检查errno是否有错误。 更好的方法是使用sscanf() ,它还允许您从字符串中解析任何基本类型,而不仅仅是整数,并且它允许您读取奇特的格式(如十六进制)。

例如,要从字符串解析整数“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");
}

如果您需要更多的错误处理,请使用正则表达式库。

答案 1 :(得分:13)

这样做:

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;
}

答案 2 :(得分:5)

参数始终作为字符串传递,您无法更改main()的原型。操作系统和周围的机器总是传递字符串,并且无法弄清楚你是否已经改变它。

您需要使用例如strtol()将字符串转换为整数。

答案 3 :(得分:2)

您想检查是否

  1. 收到0或2个参数
  2. 收到的两个值介于0和100之间
  3. 收到的参数不是字符串。如果字符串sscanf将返回 0
  4. 以下逻辑将帮助您

    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
    }
    

答案 4 :(得分:0)

你无辜地做的事情在C中是错误的。无论如何,你必须把字符串或字符作为你的论据,然后你可以随心所欲地做任何事情。要么使用strtol将它们更改为整数,要么让它们成为字符串并检查48 to 57范围内字符串的每个字符,因为它们是char 0 to 9的十进制值。就个人而言,这不是一个好主意,也不是那么好的编码实践。最好转换它们并检查你想要的整数范围。

答案 5 :(得分:-1)

您无法更改main()函数的参数。所以你应该使用atoi()函数将参数从字符串转换为整数。

atoi()有其缺点。对于strtol()或strtoul()函数也是如此。如果函数的输入是非数字的,那么这些函数将返回0值,即用户输入asdf或除有效数字之外的任何值。要解决这个问题,您需要先解析字符串,然后再将其传递给atoi()并在每个字符上调用isdigit()以确保用户输入了有效数字。之后,您可以使用atoi()转换为整数。

答案 6 :(得分:-1)

#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将字符数组转换为字符串。