【问题标题】:Printing command line arguments char by char in C在C中逐字符打印命令行参数
【发布时间】:2011-12-05 19:10:14
【问题描述】:

这是我所拥有的:

#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 测试时,输出是:

Argument!
test 4
char!
t
Segmentation Fault

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

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

【问题讨论】:

  • 这并不能解决您的问题,但是如果您想要具有复杂命令行的程序,请查看 getoptlong()
  • 你的 IDE 是什么?您是否在调试器中单步执行了代码?崩溃前 i 的值是多少?
  • 没有 IDE。 Unix 中的命令行。

标签: c arrays pointers command-line char


【解决方案1】:

第一版

你想要的是使用 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】:

试试这个:

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

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

你不能跟随 NULL 指针,因为混乱和疯狂在等待你。

【讨论】:

  • 如果你使用for (int i = 0; i &lt; argc; i++) { printf("%s\n", argv[i]); } 你不会得到Segmentation fault :-)。
【解决方案3】:

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

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

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

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

【讨论】:

    【解决方案4】:
    【解决方案5】:
    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 %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;
    }
    

    【讨论】:

      猜你喜欢
      • 2010-12-23
      • 2017-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-20
      • 2016-01-22
      • 2021-03-12
      • 2020-05-05
      相关资源
      最近更新 更多