在 C 中逐字符打印命令行参数

发布于 2024-12-09 12:10:38 字数 732 浏览 1 评论 0原文

这就是我所拥有的:

#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 语言和数组指针二元性的新手,所以如果这是问题所在,我不会感到惊讶。任何帮助表示赞赏!

Here's what I have:

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

When I run ./a.out test, the output is:

Argument!
test 4
char!
t
Segmentation Fault

I've been staring at this for a few hours. Why won't my program print each command line argument character by character?

I'm new to C, and the array-pointer duality, so I wouldn't be surprised if that were the problem. Any help is appreciated!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

心如狂蝶 2024-12-16 12:10:38

第一个版本

您想要的是使用 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;

}

First version

What you want is use 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;
}

The output is actually letter by letter as you needed:

$./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

Second version:

You can use the pointer notation for j but not for i since you don't know the letter count of each argument. It could of course be achieved by using strlen which would lead under the hood to an iteration through the string to count the letter, which is not what you want to do. If you can do it in one iteration through the argument why do it in two?

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

}
嘴硬脾气大 2024-12-16 12:10:38

试试这个:

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

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

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

Try this:

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

When you say *argv[i], if argv[i] is NULL it will fail for obvious reasons.

Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

寄居者 2024-12-16 12:10:38

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

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

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

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

You have two problems. One, you're incrementing argv to point to the next string at the beginning of each iteration of the outer while loop. When this gets to the last argument, argv will be NULL entering the last iteration, which will segfault when you dereference it.

Secondly, in the inner loop, you have the order of operations mixed. *argv[i] indexes into argv and then dereferences it, which takes the first character of the ith string, starting from the current index. When i exceeds the number of remaining arguments, this will also segfault.

Rewrite your outer loop as while(*(++argv)) (the parentheses around ++argv are optional but helpful) so that argv gets incremented before the null check; if you also want to print out the program name (in argv[0]), then move the increment to the end of the loop instead of in the loop condition.

Rewrite your inner loop as while((*argv)[i]), and rewrite the inner printf statement to also use (*argv)[i], so that the current argument gets dereferenced and then indexed into in that order.

诗酒趁年少 2024-12-16 12:10:38
  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;
}
  1. Modifying argv directly does not sound like a great idea. Make a copy and use it as you will.

  2. You cannot assume argv will at some point point to 0.

  3. Things like *argv[i] are extremely difficult to read: is that
    (*argv)[i], or *(argv[i])...

Be very careful when using pointers, otherwise you will keep on getting segfault.

The following code seems to work:

#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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文