如何打印C中main函数的argv参数?

hts6caw3  于 2023-02-07  发布在  其他
关注(0)|答案(7)|浏览(268)

所以我才知道我们可以给main函数给予两个参数,分别是“argc”和“argv”,但是我不明白argv在这里是什么:int main(int argc, char* argv[]);
argv是一个字符数组吗?还是一个指向字符的指针数组?无论哪种方式,我都在寻找一种方法来打印出用户传递给这个程序的参数,这是我写的代码,但是可以说它没有打印出argv的参数,这里面有什么问题吗?我想是我对argv的理解导致了这段代码的错误。

#include<stdio.h>
int main(int argc, char *argv[])
{
    int i;
    printf("%d\n",argc);
    for(i=0;i<argc-1;i++)
    {
        printf("%s",*argv[i]);
    }
    return 0;
}

在我从答案中得到建议之后,我对代码进行了如下修改。

#include<stdio.h>
int main(int argc, char *argv[])
{
    int i;
    printf("%d\n",argc);
    for(i=1;i<argc;i++)
    {
        printf("%s",argv[i]);
    }
    return 0;
}

我在我的windows 8.1 pc上使用的是VMWare中的Ubuntu Linux,这是我得到的输出,它只是打印了argc,然后什么都没有,有什么问题吗?是我编译它的方式还是Linux终端的什么?

在上图中,我希望再次打印数字2、4、5、3,但没有打印它们。
谢谢。

jckbn6z7

jckbn6z71#

让我们一步一步来解释。首先,当你调用你的程序时,比如...

./my-program arg0 arg1 arg2

你给它传递了一系列的三个参数,对吗?,每个参数都是一个字符串,对吗?,现在,main函数,可以有两个原型中的一个,正如C标准所规定的。

int main(); // Let's not worry about this for now
int main(int argc, char **argv);

其思想是main能够处理您提供的参数。argc提供参数的数量。如果您注意到,当传递三个参数时,argc是4!这是因为第一个参数在所有其他参数之前传递,./my-program,并让您的程序识别自己。
现在,char **argv是什么意思?X*形式的东西是X的指针,对吗?所以,char *char的指针,而char **char的指针。在C中,字符串只是char的一个以零结尾的数组,数组可以“降级”为指针,这意味着argv是一个字符串数组,其中第一个字符串argv[0]是程序名。
现在,C标准允许您为main编写任何“兼容”的原型。

int main(int argc, const char *const argv[]);
int main(int argc, const char *argv[])
int main(int argc, const char **argv);
int main(int argc, const char *const *const argv);

现在您不需要理解它们的含义,只需要知道argv是一个字符串数组,并且您永远不要修改字符串,因为原始的main原型似乎信任您。

for(int i=0;i<argc-1;i++)

表示:“对于0到argc - 1范围内的每个i“。

printf("%s",*argv[i]);

意思是:“打印argv的第i个元素的第一个字符“。为什么会出错?首先,您打印了一个char,并告诉printf它是一个字符串。这有未定义的行为。然后,您迭代了argv的第i个元素。这意味着第一个,“non-argument”元素将包含在mix中,而最后一个参数将不包含在mix中。要解决这个问题,请编写如下代码...

for(int i = 1; i < argc; i++)

表示:“对于从1argc范围内的每个i“。

printf("%s", argv[i]);

意思是:“将argv的第i个元素打印到stdout

qvtsj1bj

qvtsj1bj2#

argv是字符数组还是指向字符的指针数组?
argv是指向char的指针。当通过命令行传递参数列表时,将创建char指针数组,并且这些指针中的每一个都指向这些参数中的每一个,这些参数以字符串的形式与程序名沿着存储。argv指向此char *数组的第一个指针。因此,argv[i]是指向char的指针。

+--------------------------+
              +----+  +--> | argument 1 (program name)|
argv[0]+----> |    |  |    +--------------------------+
              |  +----+
              +----|       +--------------------------+
              |  +-------> |       argument 2         |
              |    |       +--------------------------+
              +----+
              |  +----+    +--------------------------+
              |    |  +--> |       argument 3         |
              +----+       +--------------------------+
           "char *" array

你需要改变

printf("%s",*argv[i]);

printf("%s",argv[i]);

*argv[i]的类型为char%s需要类型为char *

6qfn3psc

6qfn3psc3#

char *argv[]是指向char的指针,因为函数参数中的数组自动转换为指向数组元素的指针。
您通过向printf()传递错误类型的数据调用了 undefined behavior%s需要char*,但您传递了char(对于变量数参数,已转换为int)。
删除多余的*以取消指针的引用。

#include<stdio.h>
int main(int argc, char *argv[])
{
    int i;
    printf("%d\n",argc);
    for(i=0;i<argc-1;i++)
    {
        printf("%s",argv[i]);
    }
    return 0;
}

另外,您可能需要i<argc而不是i<argc-1,为什么不打印最后一个参数呢?

m0rkklqb

m0rkklqb4#

在你编辑的问题中,你已经修正了你的主要问题。现在注意你的提示看起来像

./mygrep245YourName@ubuntu:~/test$

这里./mygrep245是打印"5\n"后的输出。您忘记打印换行符,因此所有输出和随后的shell输出都按原样连接。最后一个参数3没有打印,因为您在循环条件中使用了i<argc-1而不是i<argci<=argc-1

pqwbnv8z

pqwbnv8z5#

argv是一个以NULL结尾的字符串数组,所以你甚至不需要argc来打印所有传递给main函数的参数,所以如果argv指向NULL,那么这就是传递的参数的结尾。
总结一下,你可以用一个简单的while循环来完成,只使用argv

while (*argv != NULL)
    {
            printf("%s\n", *argv);
            argv++;
    }
0mkxixxg

0mkxixxg6#

您可以参考document
正如你所看到的,main现在有了参数,变量argc的名字代表“参数计数”;argc包含传递给程序的参数数。变量argv的名称代表“参数向量”。向量是一维数组,argv是字符串的一维数组。每个字符串都是传递给程序的参数之一。
如果您需要打印它,只需删除 * 并尝试以下操作:

#include<stdio.h>
int main(int argc, char *argv[])
{
    int i;
    printf("%d\n",argc);
    for(i=0;i<argc-1;i++)
    {
        printf("%s",argv[i]);   //remove * from here
    }
    return 0;
}
2izufjch

2izufjch7#

关于
argv是一个字符数组?还是一个指向字符的指针数组?
argv是一个c字符串数组(其中每个c字符串都是指向字符的指针)。请考虑以下命令行:

$ your-executable arg1 "arg2 with space"

它将生成一个包含以下内容的字符串数组(伪代码)

argv[0] EQUALS "your-executable"
argv[1] EQUALS "arg1"
argv[2] EQUALS "arg2 with space"

正如其他人提到的,如果您想打印所有参数,请删除printf("%s", *argv[i]);中的 * 并修复循环条件

相关问题