C sprintf数组char指针

use*_*313 11 c arrays pointers

谁能告诉我这里我做错了什么?为什么我的程序会出现段错误?我想在string1和之间插入第三个字符串string2.

#include <stdio.h>

int main (void) 
{
char *string1 = "HELLO";
char *string2 = "WORLD";
char *stringX  = "++++";
char *string3;
printf ("%s,%s\n",string1,string2);
sprintf(string3,"%s%s%s",string1,stringX,string2);
printf ("NewVar: %s",string3);
}
Run Code Online (Sandbox Code Playgroud)

为什么不sprintf将结果值存储在指向的内存地址string3?它在我声明string3为普通数组时有效,但在它指向char数组时则无效.

我以为没有string3指向任何内存位置,但它确实在我做的时候printf("%p",string3);

输出:

# ./concat
HELLO,WORLD,0x40042
Run Code Online (Sandbox Code Playgroud)

bis*_*hop 27

想象一下,你有一堆现金要放在公文包里.你需要什么?您必须衡量现金的大小才能知道公文包的使用大小,并且您需要一个方便携带现金的手柄.

现金是你的字符串.公文包是内存空间.公文包句柄是指针.

  1. 衡量你的现金:strlen(string1) + strlen(string2) + strlen(stringX).称之为"总数".
  2. 现在得到一个足够大的公文包: malloc(total+1)
  3. 并把它放在上面: string3

把所有这些拼凑在一起......

char *string3 = malloc(strlen(string1)+strlen(stringX)+strlen(string2)+1);
sprintf(string3, "%s%s%s", string1, stringX, string2);
Run Code Online (Sandbox Code Playgroud)

那么第一次尝试出了什么问题呢?你没有公文包.你有现金,你有一个手柄,但中间没有公文包.它似乎以一种随机的方式工作,因为编译器给你一个脏垃圾站来持有现金.有时垃圾箱有空间,有时它没有空间.如果没有,我们称之为"分段错误".

只要有数据,就必须为该数据分配空间.编译器为常量字符串分配空间,例如"HELLO".但是你必须为在运行时构建的字符串分配空间.


che*_*che 9

sprintf确实存储了价值.问题是指针string3具有未初始化的值,因此您只是覆盖随机内存.

您有一个选择是使用静态字符串缓冲区:

char string3[20];
snprintf(string3, sizeof(string3), "Hello!");
Run Code Online (Sandbox Code Playgroud)

或者,您可以asprintf在基于GNU libc的系统上使用自动分配适当的空间:

char * string3;
asprintf(&string3, "Hello!");
// ... after use
free(string3); // free the allocated memory
Run Code Online (Sandbox Code Playgroud)


sim*_*onc 8

sprintf不为它写入的字符串分配内存.你必须为它写入一个有效的字符串,但是当前正在传递一个未初始化的指针.

最简单的解决方法是改变

char *string3;
sprintf(string3,"%s%s%s",string1,stringX,string2);
Run Code Online (Sandbox Code Playgroud)

char string3[200];
sprintf(string3,"%s%s%s",string1,stringX,string2);
Run Code Online (Sandbox Code Playgroud)

在这种情况下,您可能希望通过使用snprintf来防止缓冲区溢出

char string3[200];
snprintf(string3,sizeof(string3),"%s%s%s",string1,stringX,string2);
Run Code Online (Sandbox Code Playgroud)

或者,您也可以通过确定string3运行时的大小来处理更大长度的源字符串,完成后请注意free此内存.

char* string3 = malloc(strlen(string1) + strlen(stringX) + strlen(string2) + 1);
if (string3 == NULL) {
    // handle out of memory
}
sprintf(string3,"%s%s%s",string1,stringX,string2);
...
free(string3);
Run Code Online (Sandbox Code Playgroud)


Sam*_*ica 5

string3如果您需要将其放在堆上,则需要为其分配空间malloc;如果不需要,则将其声明为字符数组。