sprintf// 有自动内存分配?

我在找 sprintf//-like实现自动分配必要的内存的函数。 所以我想说


char* my_str = dynamic_sprintf/ "Hello %s, this is a %.*s nice d string", a, b, c, d /;


和 my_str 提取包含此结果的分配内存的地址 sprintf//.

在另一个论坛中,我读到它可以像这样解决:


#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main//
{
char* ret;
char* a = "Hello";
char* b = "World";
int c = 123;

int numbytes;

numbytes = sprintf/ /char*/NULL, "%s %d %s!", a, c, b /;
printf/ "numbytes = %d", numbytes /;

ret = /char*/malloc/ / numbytes + 1 / * sizeof/ char / /;
sprintf/ ret, "%s %d %s!", a, c, b /;

printf/ "ret = &gt;%s&lt;\n", ret /;
free/ ret /;

return 0;
}


但它立即导致 segfault, 叫 sprintf// 用空指针。

那么,有想法,解决方案或提示? 销量的销售额 sprintf//-like, 在开放访问中,它已经足够了,然后我可以自己做。

非常感谢!
</string.h></stdio.h></stdlib.h>
已邀请:

郭文康

赞同来自:

这是原始答案
https://coderoad.ru/1775403/
. 如上所述,你需要
snprintf

, 但不是
sprintf

. 确保第二个论点
snprintf

- 这是
zero

. 这将防止录制
snprintf

在截止日期
NULL

, 这是第一个论点。

第二个论点是必要的,因为他说
snprintf

, 什么不足以写入输出缓冲区。 在没有足够空间的情况下
snprintf

如果有足够的空间,返回它将写入的字节数。

在此处播放代码 ...


char* get_error_message/char const *msg/ {
size_t needed = snprintf/NULL, 0, "%s: %s /%d/", msg, strerror/errno/, errno/ + 1;
char *buffer = malloc/needed/;
sprintf/buffer, "%s: %s /%d/", msg, strerror/errno/, errno/;
return buffer;
}

帅驴

赞同来自:

GNU 和 BSD 有
http://linux.die.net/man/3/asprintf
和 vasprintf, 这是为此而设计的。 他会发现如何为您突出显示内存并返回 null 任何内存分配错误。

asprintf 使正确的事情与行的分配相关 - 首先它测量尺寸,然后尝试分配使用 malloc. 否则他回来了 null. 如果您没有自己的内存分配系统,可以消除使用 malloc, asprintf 这是这项工作的最佳工具。

代码将如下所示:


#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main//
{
char* ret;
char* a = "Hello";
char* b = "World";
int c = 123;

ret = asprintf/ "%s %d %s!", a, c, b /;
if /ret == NULL/ {
fprintf/stderr, "Error in asprintf\n"/;
return 1;
}

printf/ "ret = &gt;%s&lt;\n", ret /;
free/ ret /;

return 0;
}


</string.h></stdio.h></stdlib.h>

奔跑吧少年

赞同来自:

如果您可以延长扩展 GNU/BSD, 那个问题已经回答了。 您可以使用
asprintf//

/和
vasprintf//

构建包装函数/, 它会完成。


snprintf//


vsnprintf//

规定 POSIX, 根据 manpage, 后者可用于创建自己的简单版本。
asprintf//


vasprintf//

.


int
vasprintf/char **strp, const char *fmt, va_list ap/
{
va_list ap1;
size_t size;
char *buffer;

va_copy/ap1, ap/;
size = vsnprintf/NULL, 0, fmt, ap1/ + 1;
va_end/ap1/;
buffer = calloc/1, size/;

if /!buffer/
return -1;

*strp = buffer;

return vsnprintf/buffer, size, fmt, ap/;
}

int
asprintf/char **strp, const char *fmt, .../
{
int error;
va_list ap;

va_start/ap, fmt/;
error = vasprintf/strp, fmt, ap/;
va_end/ap/;

return error;
}


您可以使用一些魔术预处理器,并仅在不支持它们的系统中使用您的功能。

莫问

赞同来自:

如果可能,使用
http://libslack.org/manpages/snprintf.3.html
-- 这为测量将获得的数据大小提供了一种简单的方法,以便您可以分配一个地方。

如果你

真的

你不能这样做,另一个机会是一个临时文件的印章
fprintf

, 要获得大小,分配内存,然后使用 sprintf. 但
snprintf


确实

这是首选方法。

董宝中

赞同来自:

图书馆 GLib 提供一个功能
http://library.gnome.org/devel ... rintf
, 这使得如果绑定到你想要的东西 GLib 这是一个选择。 从文档中:

类似于标准函数 C
sprintf//

, 但更安全,就像她一样
计算最大所需空间
并分配存储内存
结果。 返回线必须是
免费S.
g_free//

, 什么时候不再
必要的。

董宝中

赞同来自:

POSIX.1 /他一样 IEEE 1003.1-2008/ 提供 open_memstream:


char *ptr;
size_t size;
FILE *f = open_memstream/&ptr, &size/;
fprintf/f, "lots of stuff here\n"/;
fclose/f/;
write/1, ptr, size/; /* for example */
free/ptr/;


open_memstream/3/ 至少可以使用 Linux 和 macOS 已经有几年了。 反向参数 open_memstream/3/ 是一个 fmemopen/3/, 这使得缓冲区的内容可访问。

如果你只需要一个 sprintf/3/, 然后广泛实施,但非标准 asprintf/3/ 也许是你需要的。

裸奔

赞同来自:

/* casprintf print to allocated or reallocated string

char *aux = NULL;
casprintf/&aux,"first line\n"/;
casprintf/&aux,"seconde line\n"/;
printf/aux/;
free/aux/;
*/
int vcasprintf/char **strp,const char *fmt,va_list ap/
{
int ret;
char *strp1;
char *result;
if /*strp==NULL/
return vasprintf/strp,fmt,ap/;

ret=vasprintf/&strp1,fmt,ap/; // ret = strlen/strp1/ or -1
if /ret == -1 / return ret;
if /ret==0/ {free/strp1/;return strlen/*strp/;}

size_t len = strlen/*strp/;
*strp=realloc/*strp,len + ret +1/;
memcpy//*strp/+len,strp1,ret+1/;
free/strp1/;
return/len+ret/;
}

int casprintf/char **strp, const char *fmt, .../
{
int ret;
va_list ap;
va_start/ap,fmt/;
ret =vcasprintf/strp,fmt,ap/;
va_end/ap/;
return/ret/;
}

要回复问题请先登录注册