使用 main(int argc,char *argv[]) 的问题
Posted
技术标签:
【中文标题】使用 main(int argc,char *argv[]) 的问题【英文标题】:Problems using main(int argc,char *argv[]) 【发布时间】:2013-04-01 16:55:40 【问题描述】:#include<stdio.h>
#include<string.h>
int main(int argc,char *argv[])
char string[]="#";
printf("%s\n",argv[1]);
printf("%s\n",argv[2]);
printf("%s\n",argv[3]);
strcat(argv[1],string);
printf("argv[1] is %s\n",argv[1]);
printf("argv[2] is %s\n",argv[2]);
printf("argv[3] is %s\n",argv[3]);
return 0;
当我使用 strcat() 在 argv[1] 末尾添加内容时,argv[2] 将丢失(使用 strcat 后 strlen(argv[2]) 变为 0)。但是 argv[3]没有变化。为什么???
【问题讨论】:
这段代码在做什么o.O' 可能与***.com/questions/963493/…重复 @Thomas 这段代码只是为了用 argv[] 解决我的问题。它没有任何意义。 【参考方案1】:您不应该修改 argv[] = 效果未定义
【讨论】:
我也是这么认为的,但是有参考吗? 其实你可以修改argv[whatever]
(指针)。修改指针指向的内容并不是很合理。
@paxdiablo:那么,是不是像char const * argv[]
?
不,它不一定是 const - 标准没有说明它必须是什么。只是内存不是你的,所以你不应该改变它。【参考方案2】:
请记住,C 中的“字符串”是以零结尾的字符数组。假设原来的四个参数是“一”、“二”、“三”和“四”;那么这四个参数在内存中存储为
one\0two\0three\0four\0
当你在 argv[1] 之后添加 # (strcat 也会添加一个 \0),内存内容变为:
one\0two#\0hree\0four\0
您现在可以验证 argv[2] 指向 \0 字符,因此它是一个空字符串。 argv[3] 仍然正确指向,并且保持不变。
【讨论】:
【参考方案3】:您不能将内容直接附加到argv[]
,因为每个argv[]
都被序列化分配到内存中只能容纳其原始大小的空间。
要了解发生了什么,想象argv
是这样的:
char buffer[] = "./program\0one\0two\0three\0";
char *argv[4] = &buffer[0], &buffer[10], &buffer[14], &buffer[18] ;
如您所见,如果您在"one"
之后写一些内容,您将覆盖"two"
并破坏整个内容,因为它们是在内存中序列化的。
要解决此问题,您必须将每个 argv[]
复制到更大的缓冲区,您可以安全地进行修改。例如:
char buf[1024];
strcpy(buf, argv[1]);
strcat(buf, string);
printf("argv[1] is %s\n", buf);
【讨论】:
以上是关于使用 main(int argc,char *argv[]) 的问题的主要内容,如果未能解决你的问题,请参考以下文章
int main(int argc, char* argv[]) 和 int main(int argc, char** argv) [关闭]
int main(int argc,char *argv[])与int main(int argc,char **argv)区别?
使用 main(int argc,char *argv[]) 的问题
int main(int argc,char* argv[])详解