连接两个字符数组 C
Concatenation of two char array C
int main(int argc, char *argv[]) {
char *s = argv[1];
*(s + (strlen(argv[1]))) = argv[2];
printf("%s \n", s);
return 0;
}
当我 运行: ./concat hello, world
输出是:
hello,Mworld
而我期待
hello,world
M
字符是什么?为什么 C 放这个?
您没有在此处追加:
*(s+(strlen(argv[1])))=argv[2];
您正在将 char*
分配给 argv[1]
的空字节,即它等同于
argv[0][strlen(argv[1])] = argv[2];
这是错误的,打开你的编译器警告以获得正确的诊断。通常,要连接字符串,您需要使用 strcat
or snprintf
。
在这种特定情况下,您不能使用 strcat
或 snprint
,因为 main()
的参数没有附加内存。所以你需要使用一个辅助数组或一个 `malloc'ed 指针来进行连接。
在尝试使用它们之前,您还应该检查是否有足够的参数传递给 main()
。
请注意,您可以修改argv[x]
。例如,如果您执行为:
./a.out stack overflow
那么你可以这样做:
argv[1][1] = 'l';
//argv[1] is now "slack"
以此类推,只要不超出其边界即可。基本上你可以像对待指针一样对待你可以修改的数组。
C11,5.1.2.2.1程序启动,p2状态
The parameters argc and argv and the strings pointed to by the argv
array shall be modifiable by the program, and retain their last-stored
values between program startup and program termination.
(强调我的)
您假设 argv[1]
足够大以包含 argv[1]
和 argv[2]
,这可能是不正确的。
最好分配一个结果缓冲区来保存连接的字符串,并尽可能避免篡改输入值(这将有助于您以后编写更复杂的代码)。
并且如果您正在修改输入,请不要假设它们的大小(取决于实现 argv[1]
可能足够大以容纳参数字符串并在意味着写入内存的相邻部分之外写入argv[1]
,可以被另一个进程的其他数据使用)。
您可能想通过回收内存来节省一些内存和一些处理器周期,但您没有检查变量是否可以保存您的结果。
'M'是第二个字符串地址的低字节
字符串恰好按顺序存储在内存中,第一个的终止空值紧接在第二个之前。 (我不认为这是你应该依赖的规则,尽管我也不知道在哪些情况下它是不真实的)。您正在用将第二个字符串的地址隐式转换为 char 的垃圾值覆盖终止 null。所以你最终在结果的两部分之间得到了那个垃圾字符。
int main(int argc, char *argv[]) {
char *s = argv[1];
*(s + (strlen(argv[1]))) = argv[2];
printf("%s \n", s);
return 0;
}
当我 运行: ./concat hello, world
输出是:
hello,Mworld
而我期待
hello,world
M
字符是什么?为什么 C 放这个?
您没有在此处追加:
*(s+(strlen(argv[1])))=argv[2];
您正在将 char*
分配给 argv[1]
的空字节,即它等同于
argv[0][strlen(argv[1])] = argv[2];
这是错误的,打开你的编译器警告以获得正确的诊断。通常,要连接字符串,您需要使用 strcat
or snprintf
。
在这种特定情况下,您不能使用 strcat
或 snprint
,因为 main()
的参数没有附加内存。所以你需要使用一个辅助数组或一个 `malloc'ed 指针来进行连接。
在尝试使用它们之前,您还应该检查是否有足够的参数传递给 main()
。
请注意,您可以修改argv[x]
。例如,如果您执行为:
./a.out stack overflow
那么你可以这样做:
argv[1][1] = 'l';
//argv[1] is now "slack"
以此类推,只要不超出其边界即可。基本上你可以像对待指针一样对待你可以修改的数组。
C11,5.1.2.2.1程序启动,p2状态
The parameters argc and argv and the strings pointed to by the argv array shall be modifiable by the program, and retain their last-stored values between program startup and program termination.
(强调我的)
您假设 argv[1]
足够大以包含 argv[1]
和 argv[2]
,这可能是不正确的。
最好分配一个结果缓冲区来保存连接的字符串,并尽可能避免篡改输入值(这将有助于您以后编写更复杂的代码)。
并且如果您正在修改输入,请不要假设它们的大小(取决于实现 argv[1]
可能足够大以容纳参数字符串并在意味着写入内存的相邻部分之外写入argv[1]
,可以被另一个进程的其他数据使用)。
您可能想通过回收内存来节省一些内存和一些处理器周期,但您没有检查变量是否可以保存您的结果。
'M'是第二个字符串地址的低字节
字符串恰好按顺序存储在内存中,第一个的终止空值紧接在第二个之前。 (我不认为这是你应该依赖的规则,尽管我也不知道在哪些情况下它是不真实的)。您正在用将第二个字符串的地址隐式转换为 char 的垃圾值覆盖终止 null。所以你最终在结果的两部分之间得到了那个垃圾字符。