2
#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] 没有变化。为什么???

4

3 回答 3

2

您不能将内容直接附加到,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);
于 2013-04-10T02:49:30.383 回答
2

请记住,C 中的“字符串”是以零结尾的字符数组。假设原来的四个参数是“一”、“二”、“三”和“四”;然后这四个参数存储在内存中

one\0two\0three\0four\0

当您在 argv[1] 之后添加 # 时(strcat 也会添加一个 \0),内存内容变为:

one\0two#\0hree\0four\0

您现在可以验证 argv[2] 是否指向 \0 字符,因此它是一个空字符串。argv[3] 仍然正确指向,并且保持不变。

于 2013-04-10T02:37:28.047 回答
0

您不应该修改 argv[] = 效果未定义

于 2013-04-10T02:29:22.747 回答