在 C 中逐字符打印命令行参数
这就是我所拥有的:
#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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
第一个版本
您想要的是使用 argc:
输出实际上是根据您的需要逐个字母:
第二个版本:
您可以使用
j
的指针表示法,但不能使用i
因为你不知道每个参数的字母数。当然可以通过使用 strlen 来实现,这会在幕后导致通过字符串迭代来计算字母,这不是您想要做的。如果你可以通过论证在一次迭代中完成它,为什么要分两次进行呢?First version
What you want is use argc:
The output is actually letter by letter as you needed:
Second version:
You can use the pointer notation for
j
but not fori
since you don't know the letter count of each argument. It could of course be achieved by usingstrlen
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?试试这个:
当你说
*argv[i]
时,如果argv[i]
为NULL,它将因明显的原因而失败。你不应该遵循 NULL 指针,因为混乱和疯狂在它的尽头等待着你。
Try this:
When you say
*argv[i]
, ifargv[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.
你有两个问题。第一,在外部
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 outerwhile
loop. When this gets to the last argument,argv
will beNULL
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 intoargv
and then dereferences it, which takes the first character of thei
th string, starting from the current index. Wheni
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 thatargv
gets incremented before the null check; if you also want to print out the program name (inargv[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 innerprintf
statement to also use(*argv)[i]
, so that the current argument gets dereferenced and then indexed into in that order.通过学习 http://faq.cprogramming.com/cgi-bin/smartfaq.cgi?answer=1046139290&id=1043284392
you will find the answer by studying http://faq.cprogramming.com/cgi-bin/smartfaq.cgi?answer=1046139290&id=1043284392
直接修改
argv
听起来并不是一个好主意。制作一个副本并按照您的意愿使用它。您不能假设
argv
在某个点会指向0
。*argv[i]
这样的东西非常难以阅读:是吗?(*argv)[i]
或*(argv[i])
...使用指针时要非常小心,否则会不断出现段错误。
以下代码似乎有效:
Modifying
argv
directly does not sound like a great idea. Make a copy and use it as you will.You cannot assume
argv
will at some point point to0
.*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: