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

时间:2016-03-08 06:46:41

标签: c printf parameter-passing

所以我才知道我们可以给主函数提供两个参数,即" 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上使用VMWare中的Ubuntu Linux。这是我得到的输出。它只是打印argc,之后什么都没有。问题是什么?这是我在Linux终端中编译它的方式吗?

The snapshot of my terminal

在上图中,我想再次打印数字2,4,5,3,但它们没有打印出来。

感谢。

6 个答案:

答案 0 :(得分:9)

让我们一步一步地解释一下。首先,当你通过调用类似的东西来调用你的程序时

./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的以零结尾的数组,并且数组可以降级为&#34;成指针。这意味着argv是一个字符串数组,其中第一个是argv[0],是程序的名称。

现在,C标准允许您编写任何&#34;兼容的&#34; 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 1}}原型似乎信任你。现在,知道参数从argv[1]开始,你的代码......

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

表示:&#34;对于0到i&#34;范围内的每个argc - 1

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

表示:&#34;打印i&#34;的argv元素的第一个字符。为什么这会错?首先,您要打印char,并告诉printf它是一个字符串。 这有未定义的行为。然后,您将迭代i的第argv个元素。这意味着第一个&#34;非参数&#34;元素将包含在混合中,最后一个参数不会被包含在内。为了解决这个问题,请写一些像......

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

表示:&#34;对于i1&#34;范围内的每个argc

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

表示:&#34;将i的{​​{1}}元素打印到argv

答案 1 :(得分:5)

  

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 *类型。

答案 2 :(得分:2)

在您编辑的问题中,您修复了主要问题。现在请注意您的提示符如

./mygrep245YourName@ubuntu:~/test$

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

答案 3 :(得分:1)

char *argv[]是指向char的指针,因为函数参数中的数组会自动转换为指向数组元素的指针。

您通过将具有错误类型的数据传递到printf()来调用未定义的行为%s期望char*,但您通过了char(已转换为int表示可变数字参数。)

删除额外的* o取消引用指针。

#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。为什么不打印最后一个参数?

答案 4 :(得分:0)

您可以参考document

  

如你所见,main现在有了参数。变量argc的名称   代表“论点数”; argc包含参数的数量   传递给该计划。变量argv的名称代表   “论证矢量”。向量是一维数组,argv是a   一维字符串数组。每个字符串都是其中一个参数   那是传递给程序的。

如果您需要打印它,只需删除*并尝试:

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

答案 5 :(得分:-1)

关于

  

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]);中删除*并修复循环条件