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

时间:2022-09-06 14:09:22

I would like a user to pass either two parameters or leave it blank. For instance:

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

./program 50 50

or

./program

When I tried to use int main(int argc, char *argv[]), first thing I have done was to change char *argv[] to int *argv[] but it did not work. What I want is from the user is just to enter two integers between 0 and 100. So if it is not two integers then it should give an error.

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

I was sort of thinking to give out an error with types (as I used to program on C#) but whatever I enter, argv[1] would be 'char' type all the time.

我想在类型上给出一个错误(正如我在c#上编程时所做的),但是无论我输入什么,argv[1]始终是“char”类型。

So what I have done is

我所做的是

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

This does not work as well. Also it gives warning when compiling, but if I change argv with atoi(argv[1]) for instance, then it gives a Segmentation fault (core dumped) error.

这并不是很有效。它在编译时也会给出警告,但是如果我用atoi(argv[1])更改argv,那么它会产生一个分割错误(核心转储)错误。

I need a simple way to solve this problem.

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

EDIT:

编辑:

So I fixed with atoi(), the reason why it was giving segmentation fault was because I was trying it with null value when I have no parameter. So I fixed it up by adding an extra cond. But now the problem is if the value is let's say

所以我修正了atoi(),它给出分割错误的原因是因为我在没有参数的情况下用null值来尝试。所以我通过添加额外的cond来修复它。但现在问题是,如果这个值是。

./program asd asd

Then the output of atoi(argv[1]) would be 0. Is there a way to change this value?

那么atoi(argv[1])的输出就是0。有办法改变这个值吗?

8 个解决方案

#1


28  

Don't use atoi() and don't use strtol(). atoi() has no error checking (as you found out!) and strtol() has to be error-checked using the global errno variable, which means you have to set errno to 0, then call strtol(), then check errno again for errors. A better way is to use sscanf(), which also lets you parse any primitive type from a string, not just an integer, and it lets you read fancy formats (like hex).

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

For example, to parse integer "1435" from a string:

例如,从字符串中解析整数“1435”:

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

To parse a single character 'Z' from a string

从字符串中解析单个字符“Z”

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

To parse a float "3.1459" from a string

从字符串中解析浮点数“3.1459”

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

To parse a large unsigned hexadecimal integer "0x332561" from a string

从字符串中解析一个大的未签名的十六进制整数“0x332561”。

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

If you need more error-handling than that, use a regex library.

如果您需要更多的错误处理,请使用regex库。

#2


12  

This will do:

这将会做的事:

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


5  

The arguments are always passed as strings, you can't change the prototype of main(). The operating system and surrounding machinery always pass strings, and are not able to figure out that you've changed it.

参数总是作为字符串传递,您不能更改main()的原型。操作系统和周围的机器总是传递字符串,无法确定您已经更改了它。

You need to use e.g. strtol() to convert the strings to integers.

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

#4


2  

You want to check whether

你要检查一下

  1. 0 or 2 argument is received
  2. 接收到0或2个参数
  3. two values received are between 0 and 100
  4. 接收到的两个值在0到100之间
  5. received argument is not a string. If string comes sscanf will return 0.
  6. 接收的参数不是字符串。如果字符串出现,sscanf将返回0。

Below logic will helps you

下面的逻辑将帮助你

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


0  

The things you have done so innocently are blunder in C. No matter what, you have to take strings or chars as your arguments and then later you can do whatever you like with them. Either change them to integer using strtol or let them be the strings and check each char of the string in the range of 48 to 57 as these are the decimal values of char 0 to 9. Personally, this is not a good idea and not so good coding practice. Better convert them and check for the integer range you want.

不管怎样,你必须把字符串或字符作为你的参数,然后你可以用它们做任何你喜欢做的事情。或者使用strtol将它们更改为整数,或者让它们为字符串,并在48到57之间检查字符串的每个字符,因为这些是char 0到9的十进制值。就我个人而言,这不是一个好主意,也不是一个好的编码实践。最好转换它们并检查您想要的整数范围。

#6


0  

You can still use atoi, just check whether the argument is a number first ;)
btw ppl will tell you goto is evil, but they're usually brainwashed by non-sensible "goto is bad", "goto is evil", "goto is the devil" statements that were just tossed out without elaboration on the internet.
Yes, spaggethi code is less managable. And goto in that context is from an age where it replaced functions...

你仍然可以使用atoi,仅仅检查论点是否是一个数字;)顺便说一句,ppl会告诉你后藤是邪恶的,但是他们通常被不理智的“后藤是坏的”,“后藤是恶的”,“后藤是魔鬼”的陈述*,这些陈述在互联网上没有详细说明。是的,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


-1  

You can not change the arguments of main() function. So you should just use atoi() function to convert arguments from string to integer.

不能更改main()函数的参数。因此,您应该使用atoi()函数来将参数从字符串转换为整数。

atoi() has its drawbacks. Same is true for strtol() or strtoul() functions. These functions will return a 0 value if the input to the function is non-numeric i.e user enters asdf or anything other than a valid number. To overcome this you will need to parse the string before passing it to atoi() and call isdigit() on each character to make sure that the user has input a valid number. After that you can use atoi() to convert to integer.

atoi()有其缺陷。strtol()或strtoul()函数也是如此。如果函数的输入不是数值i,那么这些函数将返回0。e用户输入asdf或除有效号码以外的任何内容。要克服这个问题,您需要在将字符串传递给atoi()并在每个字符上调用isdigit(),以确保用户输入了有效的数字。之后可以使用atoi()将其转换为整数。

#8


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

  }

check this program i added another library stdlib.h and so i can convert the character array to string using function atoi.

检查这个程序,我添加了另一个库stdlib。我可以用函数atoi将字符数组转换成字符串。

#1


28  

Don't use atoi() and don't use strtol(). atoi() has no error checking (as you found out!) and strtol() has to be error-checked using the global errno variable, which means you have to set errno to 0, then call strtol(), then check errno again for errors. A better way is to use sscanf(), which also lets you parse any primitive type from a string, not just an integer, and it lets you read fancy formats (like hex).

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

For example, to parse integer "1435" from a string:

例如,从字符串中解析整数“1435”:

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

To parse a single character 'Z' from a string

从字符串中解析单个字符“Z”

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

To parse a float "3.1459" from a string

从字符串中解析浮点数“3.1459”

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

To parse a large unsigned hexadecimal integer "0x332561" from a string

从字符串中解析一个大的未签名的十六进制整数“0x332561”。

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

If you need more error-handling than that, use a regex library.

如果您需要更多的错误处理,请使用regex库。

#2


12  

This will do:

这将会做的事:

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


5  

The arguments are always passed as strings, you can't change the prototype of main(). The operating system and surrounding machinery always pass strings, and are not able to figure out that you've changed it.

参数总是作为字符串传递,您不能更改main()的原型。操作系统和周围的机器总是传递字符串,无法确定您已经更改了它。

You need to use e.g. strtol() to convert the strings to integers.

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

#4


2  

You want to check whether

你要检查一下

  1. 0 or 2 argument is received
  2. 接收到0或2个参数
  3. two values received are between 0 and 100
  4. 接收到的两个值在0到100之间
  5. received argument is not a string. If string comes sscanf will return 0.
  6. 接收的参数不是字符串。如果字符串出现,sscanf将返回0。

Below logic will helps you

下面的逻辑将帮助你

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


0  

The things you have done so innocently are blunder in C. No matter what, you have to take strings or chars as your arguments and then later you can do whatever you like with them. Either change them to integer using strtol or let them be the strings and check each char of the string in the range of 48 to 57 as these are the decimal values of char 0 to 9. Personally, this is not a good idea and not so good coding practice. Better convert them and check for the integer range you want.

不管怎样,你必须把字符串或字符作为你的参数,然后你可以用它们做任何你喜欢做的事情。或者使用strtol将它们更改为整数,或者让它们为字符串,并在48到57之间检查字符串的每个字符,因为这些是char 0到9的十进制值。就我个人而言,这不是一个好主意,也不是一个好的编码实践。最好转换它们并检查您想要的整数范围。

#6


0  

You can still use atoi, just check whether the argument is a number first ;)
btw ppl will tell you goto is evil, but they're usually brainwashed by non-sensible "goto is bad", "goto is evil", "goto is the devil" statements that were just tossed out without elaboration on the internet.
Yes, spaggethi code is less managable. And goto in that context is from an age where it replaced functions...

你仍然可以使用atoi,仅仅检查论点是否是一个数字;)顺便说一句,ppl会告诉你后藤是邪恶的,但是他们通常被不理智的“后藤是坏的”,“后藤是恶的”,“后藤是魔鬼”的陈述*,这些陈述在互联网上没有详细说明。是的,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


-1  

You can not change the arguments of main() function. So you should just use atoi() function to convert arguments from string to integer.

不能更改main()函数的参数。因此,您应该使用atoi()函数来将参数从字符串转换为整数。

atoi() has its drawbacks. Same is true for strtol() or strtoul() functions. These functions will return a 0 value if the input to the function is non-numeric i.e user enters asdf or anything other than a valid number. To overcome this you will need to parse the string before passing it to atoi() and call isdigit() on each character to make sure that the user has input a valid number. After that you can use atoi() to convert to integer.

atoi()有其缺陷。strtol()或strtoul()函数也是如此。如果函数的输入不是数值i,那么这些函数将返回0。e用户输入asdf或除有效号码以外的任何内容。要克服这个问题,您需要在将字符串传递给atoi()并在每个字符上调用isdigit(),以确保用户输入了有效的数字。之后可以使用atoi()将其转换为整数。

#8


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

  }

check this program i added another library stdlib.h and so i can convert the character array to string using function atoi.

检查这个程序,我添加了另一个库stdlib。我可以用函数atoi将字符数组转换成字符串。