C语言 C sprintf 数组字符指针

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19772667/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 07:52:58  来源:igfitidea点击:

C sprintf array char pointers

carrayspointers

提问by user2953313

Could anyone tell me what am i doing wrong over here? Why does my program segfault ? I am trying to insert a third string between string1and string2.

谁能告诉我我在这里做错了什么?为什么我的程序段错误?我正在尝试在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);
}

Why doesn't sprintfstore the resultant value at the memory address pointed by string3? It works when i declare string3as an ordinary array but not when its a pointer to chararray.

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

I thought string3wasnt pointing to any memory location, but it does seem to when i do printf("%p",string3);

我以为没有string3指向任何内存位置,但是当我这样做时似乎确实如此printf("%p",string3);

Output:

输出:

# ./concat
HELLO,WORLD,0x40042

回答by bishop

Imagine you have a pile of cash that you want to put in a briefcase. What do you need? You have to measure the size of the cash to know how big a briefcase to use, and you need a handle to conveniently carry the cash around.

想象一下,您有一堆现金要放在公文包中。你需要什么?您必须测量现金的大小才能知道使用多大的公文包,并且您需要一个把手来方便地携带现金。

The cash is your strings. The briefcase is memory space. The briefcase handle is the pointer.

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

  1. Measure your cash: strlen(string1) + strlen(string2) + strlen(stringX). Call this "total".
  2. Now get a big enough briefcase: malloc(total+1)
  3. And put a handle on it: string3
  1. 衡量您的现金:strlen(string1) + strlen(string2) + strlen(stringX). 称其为“总计”。
  2. 现在得到一个足够大的公文包: malloc(total+1)
  3. 并在其上放一个把手: string3

Cobbling all that together...

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

char *string3 = malloc(strlen(string1)+strlen(stringX)+strlen(string2)+1);
sprintf(string3, "%s%s%s", string1, stringX, string2);

So what was wrong with the first attempt?You had no briefcase. You have cash, and you have a handle, but no briefcase in the middle. It appeared to work, in a random kind of way, because the compiler gave you a dirty dumpster to hold the cash. Sometimes the dumpster has room, sometimes it doesn't. When it doesn't, we call that "segmentation fault".

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

Whenever you have data, you have to allocate space for that data. The compiler allocates space for your constant strings, like "HELLO". But you have to allocate space for strings built at run-time.

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

回答by che

sprintfdoes store the value there. The problem is that the pointer string3 has uninitialized value, so you're just overwriting random memory.

sprintf确实将值存储在那里。问题是指针 string3 具有未初始化的值,因此您只是覆盖随机内存。

One option you have is to use static string buffer:

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

char string3[20];
snprintf(string3, sizeof(string3), "Hello!");

Or, you can use asprintfon GNU libc-based systems to allocate proper space automatically:

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

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

回答by simonc

sprintfdoes not allocate memory for the string it writes. You have to provide a valid string for it to write into but are currently passing it an uninitialised pointer.

sprintf不会为其写入的字符串分配内存。您必须提供一个有效的字符串才能写入,但当前正在向它传递一个未初始化的指针。

The easiest fix is to change

最简单的解决方法是改变

char *string3;
sprintf(string3,"%s%s%s",string1,stringX,string2);

to

char string3[200];
sprintf(string3,"%s%s%s",string1,stringX,string2);

You may want to guard against buffer overflows in this case by using snprintfinstead

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

char string3[200];
snprintf(string3,sizeof(string3),"%s%s%s",string1,stringX,string2);

Alternatively, you could also cope with larger lengths of source string by determining the size of string3at runtime, taking care to freethis memory when you have finished with it.

或者,您还可以通过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);

回答by Sam I am says Reinstate Monica

you need to allocate space for string3either with mallocif you need it to be on the heap, or declare it as a character array if you don't.

如果您需要它在堆上,则需要为string3其中之一分配空间,或者malloc如果不需要,则将其声明为字符数组。