在C中一个字符一个字符地打印命令行参数



我有:

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

当我运行。/a。输出测试,输出为:

Argument!
test 4
char!
t
Segmentation Fault

我已经盯着这个看了几个小时了。为什么我的程序不能逐字符打印每个命令行参数?

我是C的新手,数组指针二象性,所以如果这是问题,我不会感到惊讶。任何帮助都是感激的!

初版

你想要的是使用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] != '')
       printf("Argument %d letter %d : %cn", 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) != '')
    {
            printf("Argument %d letter %d : %cn", i,j,*(argv[i]+(j)));
            j++;
    } 
     i++;
    }
    return 0;
}

试试这个:

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

当你说*argv[i]时,如果argv[i]是NULL,它将失败,原因很明显

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

你有两个问题。首先,在外部while循环的每次迭代开始时,增加argv以指向下一个字符串。当到达最后一个参数时,argv将是NULL,进入最后一次迭代,当您解引用它时,它将出现段错误。

其次,在内循环中,操作顺序是混合的。*argv[i]索引到argv,然后对其解引用,取i字符串的第一个字符,从当前索引开始。当i超过剩余参数的数量时,也会出现段错误。

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

将内部循环重写为while((*argv)[i]),并将内部printf语句重写为也使用(*argv)[i],以便当前参数被解引用,然后按该顺序索引

你会通过研究http://faq.cprogramming.com/cgi-bin/smartfaq.cgi?answer=1046139290&id=1043284392找到答案的

  1. 直接修改argv听起来不像是一个好主意。复制一份,随意使用

  2. 你不能假设argv会在某个点指向0

  3. *argv[i]这样的东西是非常难以阅读的:是吗(*argv)[i],或*(argv[i])

在使用指针的时候要非常小心,否则你会一直得到段错误。

下面的代码似乎可以工作:

#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 %dn",currentArgv[currentArgc],(int)strlen(currentArgv[currentArgc]));
            int i = 0;
            while(currentArgv[currentArgc][i]!='')
            {
                    printf("char!n");
                    printf("%cn",currentArgv[currentArgc][i]);
                        i++;
            }
            printf("End of for loopn");
    }
    return 0;
}

最新更新