在C中用char打印命令行参数char

时间:2011-10-12 03:14:37

标签: c arrays pointers command-line char

这就是我所拥有的:

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

int main(int argc, char **argv)
{

    while(*argv++ != 0)
    {
            printf("Argument!\n");
            printf("%s %d\n",*argv,(int)strlen(*argv));
            int i = 0;

            while(*argv[i])
            {
                    printf("char!\n");
                    printf("%c\n",*argv[i]);
                    i++;
            }

            printf("End of for loop\n");
    }

    return 0;
}

当我运行./a.out test时,输出为:

Argument!
test 4
char!
t
Segmentation Fault

我一直盯着这几个小时。为什么我的程序不会逐个字符地打印每个命令行参数?

我是C的新手,以及数组指针的二元性,所以如果这是问题,我不会感到惊讶。任何帮助表示赞赏!

5 个答案:

答案 0 :(得分:4)

试试这个:

while(argv) {
    printf("%s\n", *argv); /* %s instead of %c and drop [i]. */
    argv++; /* Next arg. */
}

当您说*argv[i]时,如果argv[i]为NULL,则会因显而易见的原因而失败

你不应该遵循NULL指针,因为混乱和疯狂等待着你。

答案 1 :(得分:4)

第一个版本

你想要的是使用argc:

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

int main(int argc, char **argv)
{
    int i = 0;
    int j = 0;
    for (i = 0; i < argc; i ++)
    {
    j = 0;      
    while(argv[i][j] != '\0')
       printf("Argument %d letter %d : %c\n", i,j,argv[i][j++]);   
    }
    return 0;
}

输出实际上是您需要的字母:

$./a.out hello world
Argument 0 letter 1 : .
Argument 0 letter 2 : /
Argument 0 letter 3 : a
Argument 0 letter 4 : .
Argument 0 letter 5 : o
Argument 0 letter 6 : u
Argument 0 letter 7 : t
Argument 1 letter 1 : h
Argument 1 letter 2 : e
Argument 1 letter 3 : l
Argument 1 letter 4 : l
Argument 1 letter 5 : o
Argument 2 letter 1 : w
Argument 2 letter 2 : o
Argument 2 letter 3 : r
Argument 2 letter 4 : l
Argument 2 letter 5 : d

第二版:

您可以使用j的指针表示法,但不能使用i的指针表示法,因为您不知道每个参数的字母数。它当然可以通过使用strlen来实现,它会引导通过字符串迭代来计算字母,这不是你想要做的。如果你可以通过参数在一次迭代中完成它为什么要用两个呢?

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

int main(int argc, char **argv)
{
    int i = 0;int j = 0;
    while(i < argc)
    {
    j=0;
    while(*(argv[i]+j) != '\0')
    {
            printf("Argument %d letter %d : %c\n", i,j,*(argv[i]+(j)));
            j++;
    } 
     i++;
    }
    return 0;

}

答案 2 :(得分:2)

你有两个问题。一,你将argv递增到指向外while循环每次迭代开始时的下一个字符串。当这到达最后一个参数时,argvNULL进入最后一次迭代,当你取消引用它时会出现段错误。

其次,在内部循环中,您将混合操作顺序。 *argv[i]argv索引到i,然后取消引用它,它从当前索引开始获取i字符串的第一个字符。当while(*(++argv))超过剩余参数的数量时,这也将是段错误。

将外部循环重写为++argvargv周围的括号是可选的但很有用),以便{<1}}在空检查之前增加;如果您还想打印出程序名称(在argv[0]中),则将增量移动到循环的末尾而不是循环条件。

将内部循环重写为while((*argv)[i]),并重写内部printf语句以使用(*argv)[i],以便取消引用当前参数,然后按此顺序编入索引。

答案 3 :(得分:2)

答案 4 :(得分:1)

  1. 直接修改argv并不是一个好主意。制作副本并按照您的意愿使用它。

  2. 您不能认为argv会在某个时间点指向0

  3. *argv[i]这样的事情非常难以阅读:就是这样 (*argv)[i]*(argv[i]) ...
  4. 使用指针时要非常小心,否则你会继续遇到段错误。

    以下代码似乎有效:

    #include <stdlib.h>
    #include <string.h>
    #include <stdio.h>
    
    int main(int argc, char **argv)
    {
        char **currentArgv = argv;
        int currentArgc = 0;
        while(++currentArgc < argc)
        {
                printf("Argument!\n");
                printf("%s %d\n",currentArgv[currentArgc],(int)strlen(currentArgv[currentArgc]));
                int i = 0;
    
                while(currentArgv[currentArgc][i]!='\0')
                {
                        printf("char!\n");
                        printf("%c\n",currentArgv[currentArgc][i]);
                            i++;
                }
    
                printf("End of for loop\n");
        }
    
        return 0;
    }