17

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

./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()它,它给出分段错误的原因是因为我在没有参数的情况下尝试使用空值。所以我通过添加一个额外的条件来修复它。但现在的问题是,如果值是让我们说

./program asd asd

那么 的输出atoi(argv[1])将为 0。有没有办法改变这个值?

4

8 回答 8

30

不使用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");
}

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

于 2012-08-23T13:21:06.483 回答
14

这将做:

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;
}
于 2012-08-23T12:11:49.677 回答
5

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

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

于 2012-08-23T12:02:24.190 回答
2

你想检查是否

  1. 收到 0 或 2 个参数
  2. 收到的两个值介于 0 和 100 之间
  3. 收到的参数不是字符串。如果字符串来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
}
于 2012-08-23T14:12:18.863 回答
0

仍然可以使用atoi,只需先检查参数是否为数字;)
顺便说一句,人们会告诉您 goto 是 邪恶的,但他们通常会被不明智的 “goto is bad”“goto is evil”“goto ”洗脑是魔鬼”的 言论,只是在互联网上未经详细说明就被扔掉了。
是的,意大利面条代码不太容易管理。在这种情况下 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;
    }
于 2015-04-29T22:29:06.127 回答
0

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

于 2012-08-23T12:09:20.750 回答
-1

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

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

于 2012-08-23T12:04:47.770 回答
-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将字符数组转换为字符串。

于 2015-11-21T12:53:00.467 回答