使用 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[])详解

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

int main(int argc,char **argv)[重复]