遍历argv []

J. *_*ken 3 c arrays pointers

我是C的新手,我完成了一个小练习,该练习遍历传递给它的参数中的字母并识别元音。初始代码仅适用于一个参数(argv[1])。我想扩展它,以便能够遍历所有参数,argv[]并重复识别元音的相同过程。

代码:

#include <stdio.h>

int main(int argc, char *argv[])
{
    if (argc < 2) {
        printf("ERROR: You need at least one argument.\n");
        return 1;
    }

    if (argc == 2) {
        int i = 0;
        for (i = 0; argv[1][i] != '\0'; i++) {
            char letter = argv[1][i];

            if (letter == 'A' || letter == 'a') {
                printf("%d: 'A'\n", i);
                //so on
            }
        }
    } else {
        int i = 0;
        int t = 2;
        for (t = 2; argv[t] != '\0'; t++) {
            for (i = 0; argv[t][i] != '\0'; i++) {
                char letter = argv[t][i];

                if //check for vowel
            }

        }

        return 0;
    }
}
Run Code Online (Sandbox Code Playgroud)

我读了这个答案,看来最好的解决方案是使用指针,这个概念我仍然有些犹豫。我希望有人可以使用此问题的上下文来帮助我更好地理解指针(通过解释在这种情况下使用指针如何解决当前的问题)。提前谢谢了。

H.S*_*.S. 7

I was hoping someone could use the context of this question to help me understand pointers better....

在您的程序中:

int main(int argc, char *argv[])
Run Code Online (Sandbox Code Playgroud)

首先,要明白什么是argcargv这里。

argc(自变量计数):是从命令行传递到程序中的自变量数目,包括程序名称。

argv(参数向量):指向传递的字符串参数的字符指针数组。

关于argv以下几点:

  • 指向的字符串argv[0]表示程序名称。

  • argv[argc] 是一个空指针。

为了更好地理解,让我们考虑一个示例:

假设您要将一些命令行参数传递给程序-

# test have a nice day
Run Code Online (Sandbox Code Playgroud)

test是可执行文件的名称和haveaniceday传递给它,在这种情况下的参数,参数计数(argc)会5

参数向量(argv)在内存中的视图将如下所示:

      argv                       --
        +----+    +-+-+-+-+--+     |
 argv[0]|    |--->|t|e|s|t|\0|     |
        |    |    +-+-+-+-+--+     |
        +----+    +-+-+-+-+--+     |
 argv[1]|    |--->|h|a|v|e|\0|     |
        |    |    +-+-+-+-+--+     |
        +----+    +-+--+           |
 argv[2]|    |--->|a|\0|            > Null terminated char array (string)
        |    |    +-+--+           |
        +----+    +-+-+-+-+--+     |
 argv[3]|    |--->|n|i|c|e|\0|     |
        |    |    +-+-+-+-+--+     |
        +----+    +-+-+-+--+       |
 argv[4]|    |--->|d|a|y|\0|       |
        |    |    +-+-+-+--+       |
        +----+                   --
 argv[5]|NULL|
        |    |
        +----+
Run Code Online (Sandbox Code Playgroud)

需要注意的一点是关于字符串(以空终止的字符数组),它会衰减为分配给type的指针char*

由于argv(argument vector)是指向传递的字符串参数的指针数组。所以,

argv+0 --> will give address of first element of array.
argv+1 --> will give address of second element of array.
...
...
and so on.
Run Code Online (Sandbox Code Playgroud)

我们还可以像这样获得数组第一个元素的地址- &argv[0]

这意味着:

argv+0 and &argv[0] are same.
Run Code Online (Sandbox Code Playgroud)

同样,

argv+1 and &argv[1] are same.
argv+2 and &argv[2] are same.
...
...
and so on.
Run Code Online (Sandbox Code Playgroud)

取消引用它们时,将获得它们指向的字符串:

*(argv+0) --> "test"
*(argv+1) --> "have"
....
....
and so on.
Run Code Online (Sandbox Code Playgroud)

同样,

*(&argv[0]) --> "test"
Run Code Online (Sandbox Code Playgroud)

*(&argv[0])也可以写成argv[0]

意思是:

*(argv+0) can also written as argv[0]. 
Run Code Online (Sandbox Code Playgroud)

所以,

*(argv+0) and argv[0] are same
*(argv+1) and argv[1] are same
...
...
and so on.
Run Code Online (Sandbox Code Playgroud)

打印它们时:

printf ("%s", argv[0]);   //---> print "test"
printf ("%s", *(argv+0)); //---> print "test"
printf ("%s", argv[3]);   //---> print "nice"
printf ("%s", *(argv+3)); //---> print "nice"
Run Code Online (Sandbox Code Playgroud)

而且由于参数向量的最后一个元素是NULL,当我们访问时,argv[argc]我们得到NULL

要访问字符串字符:

argv[1] is a string --> "have"
argv[1][0] represents first character of string --> 'h'

As we have already seen:
argv[1] is same as *(argv+1)

So,
argv[1][0] is same as *(*(argv+1)+0)
Run Code Online (Sandbox Code Playgroud)

要访问字符串“ have”的第二个字符,可以使用:

argv[1][1] --> 'a'
or,
*(*(argv+1)+1) --> 'a'
Run Code Online (Sandbox Code Playgroud)

我希望这将帮助您更好地理解问题中的指针。

要确定传递给程序的参数中的元音,可以执行以下操作:

#include <stdio.h>

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

    if (argc < 2) {
            printf("ERROR: You need at least one argument.\n");
            return -1;
    }

    for (char **pargv = argv+1; *pargv != argv[argc]; pargv++) {
            /* Explaination:
             * Initialization -
             * char **pargv = argv+1; --> pargv pointer pointing second element of argv
             *                            The first element of argument vector is program name
             * Condition -
             * *pargv != argv[argc]; --> *pargv iterate to argv array
             *                            argv[argc] represents NULL
             *                            So, the condition is *pargv != NULL
             *                            This condition (*pargv != argv[argc]) is for your understanding
             *                            If using only *pragv is also okay 
             * Loop iterator increment -
             * pargv++
             */

            printf ("Vowels in string \"%s\" : ", *pargv);
            for (char *ptr = *pargv; *ptr != '\0'; ptr++) {
                    if (*ptr == 'a' || *ptr == 'e' || *ptr == 'i' || *ptr == 'o' || *ptr == 'u'
                    ||  *ptr == 'A' || *ptr == 'E' || *ptr == 'I' || *ptr == 'O' || *ptr == 'U') {
                            printf ("%c ", *ptr);
                    }
            }
            printf ("\n");
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出:

#./a.out have a nice day
Vowels in string "have" : a e 
Vowels in string "a" : a 
Vowels in string "nice" : i e 
Vowels in string "day" : a
Run Code Online (Sandbox Code Playgroud)