我对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;
}
}我读过this answer,似乎最好的解决方案是使用指针,这个概念我仍然有点动摇。我希望有人能够利用这个问题的上下文来帮助我更好地理解指针(通过解释如何在这个实例中使用指针来解决手头的问题)。在此之前,非常感谢您。
发布于 2018-01-19 18:36:02
I was hoping someone could use the context of this question to help me understand pointers better....
在您的项目中:
int main(int argc, char *argv[])首先,了解这里的argc和argv是什么。
**是从命令行传递给程序的参数数,包括程序的名称。
**指向传递的字符串参数的字符指针数组。
关于argv的几点看法
argv[0]指向的字符串表示程序名。argv[argc]是一个空指针。为了更好地理解,让我们考虑一个例子:
假设你把一些命令行参数传递给一个程序-
# test have a nice daytest是可执行文件的名称,have、a、nice和day是传递给它的参数,在本例中,参数计数(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|
| |
+----+关于字符串(以空结尾的字符数组)的一点,它衰变为指针,指针被分配给char*类型。
因为argv (参数向量)是指向传递的字符串参数的指针数组。所以,
argv+0 --> will give address of first element of array.
argv+1 --> will give address of second element of array.
...
...
and so on.我们还可以获得数组的第一个元素的地址,如&argv[0]。
这意味着:
argv+0 and &argv[0] are same.类似地,
argv+1 and &argv[1] are same.
argv+2 and &argv[2] are same.
...
...
and so on.当您取消对它们的引用时,您将得到它们所指向的字符串:
*(argv+0) --> "test"
*(argv+1) --> "have"
....
....
and so on.类似地,
*(&argv[0]) --> "test"*(&argv[0])也可以编写为argv[0]。
这意味着:
*(argv+0) can also written as argv[0]. 所以,
*(argv+0) and argv[0] are same
*(argv+1) and argv[1] are same
...
...
and so on.印刷时:
printf ("%s", argv[0]); //---> print "test"
printf ("%s", *(argv+0)); //---> print "test"
printf ("%s", argv[3]); //---> print "nice"
printf ("%s", *(argv+3)); //---> print "nice"由于参数向量的最后一个元素是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)要访问字符串“can”的第二个字符,可以使用:
argv[1][1] --> 'a'
or,
*(*(argv+1)+1) --> 'a'我希望这将有助于你更好地理解你的问题背景下的指针。
要识别传递给程序的参数中的元音,可以这样做:
#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;
}输出:
#./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发布于 2018-01-19 03:00:22
可以使用嵌套的for循环循环遍历所有参数。argc将告诉您参数的数量,而argv则包含数组。我还使用了来自strlen()库的strings函数。它会告诉你绳子有多长。这样,您就可以检查任意数量的参数。您的if语句也可以更改为2,argc小于2或大于2。
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[]) {
if (argc < 2) {
printf("ERROR: You need at least one argument.\n");
return 1;
} else {
int i, x;
int ch = 0;
for (i=1; i<argc; i++) {
for (x = 0; x < strlen(argv[i]); x++) {
ch = argv[i][x];
if (ch == 'A' || ch == 'a' || ch == 'e')
printf('Vowel\n');
}
}
}
}与嵌套循环等效的Python
for i in range (0, argc):
for x in range(0, len(argv[i])):
ch = argv[i][x];
if ch in ('A', 'a', 'e'):
print('Vowel')发布于 2018-01-19 05:32:24
虽然您可以使用多个条件表达式来测试当前字符是否为元音,但创建一个包含要测试的集合的所有可能成员的常量字符串(此处的元音)并在您的元音字符串上循环以确定当前字符是否匹配,通常是有益的。
与循环不同,您可以简单地使用常量字符串作为对strchr的调用中测试的字符串,以确定当前字符是否是集合的成员。
以下简单地使用一个循环和一个指针来迭代每个参数中的每个字符,并以相同的方式迭代我们的常量字符串char *vowels = "aeiouAEIOU";中的每个字符,以确定当前字符是否为元音(处理小写和大写形式)。
#include <stdio.h>
int main (int argc, char *argv[]) {
int i, nvowels = 0;
char *vowels = "aeiouAEIOU";
if (argc < 2) {
fprintf (stderr, "ERROR: You need at least one argument.\n");
return 1;
}
for (i = 1; i < argc; i++) { /* loop over each argument */
char *p = argv[i]; /* pointer to 1st char in argv[i] */
int vowelsinarg = 0; /* vowels per argument (optional) */
while (*p) { /* loop over each char in arg */
char *v = vowels; /* pointer to 1st char in vowels */
while (*v) { /* loop over each char in vowels */
if (*v == *p) { /* if char is vowel */
vowelsinarg++; /* increment number */
break; /* bail */
}
v++; /* increment pointer to vowels */
}
p++; /* increment pointer to arg */
}
printf ("argv[%2d] : %-16s (%d vowels)\n", i, argv[i], vowelsinarg);
nvowels += vowelsinarg; /* update total number of vowels */
}
printf ("\n Total: %d vowles\n", nvowels);
return 0;
}示例使用/输出
$ ./bin/argvowelcnt My dog has FLEAS.
argv[ 1] : My (0 vowels)
argv[ 2] : dog (1 vowels)
argv[ 3] : has (1 vowels)
argv[ 4] : FLEAS. (2 vowels)
Total: 4 vowles如果您决定使用来自strchar的string.h函数来检查当前字符是否在您的vowels集合中,那么您对每个字符的内环将缩减为:
while (*p) { /* loop over each char in arg */
if (strchr (vowels, *p)) /* check if char is in vowels */
vowelsinarg++; /* increment number */
p++; /* increment pointer to arg */
}仔细考虑一下,如果你还有其他问题,请告诉我。
https://stackoverflow.com/questions/48333430
复制相似问题