【发布时间】:2022-01-30 11:31:07
【问题描述】:
主要问题
我在使用 vsnprintf 时得到了一些意想不到的结果。在下面的代码中,我使用了 snprintf 并传递了一个空目标指针来找出它需要多少空间
#define long_string 256
typedef char STRING_VARIABLE [long_string + 1];
void SAFE_snprintf( char * buffer, char * format ,... )
{
va_list args;
va_start(args, format);
int m = vsnprintf (0, 0, format, args);
printf("m = %d\n", m);
if (m < 0)
{
perror ("snprintf failed");
abort ();
}
// Allocating memory
char *bufferString = (char *) malloc (n - 1);
if (!bufferString)
{
perror ("malloc failed");
abort ();
}
m = vsnprintf (bufferString, (n - 1), format, args);
if (m < 0)
{
perror ("vsnprintf failed");
abort ();
}
strcpy(buffer, bufferString);
free (bufferString);
va_end(args);
}
int main(int argc, char * argv[])
{
char InputString [] = "Hello";
STRING_VARIABLE bufferStrings;
char format [] = "%s_test";
int n = snprintf (0, 0, "%s_test", InputString);
if (n < 0)
{
perror ("vsnprintf failed");
abort ();
}
printf("n = %d", n);
SAFE_snprintf(bufferStrings, format , InputString);
return 0;
}
以上代码返回
n = 7
m = 10
我不确定为什么 snprintf 返回 7(这是正确的),而 vsnprintf 返回 10。我认为这是错误的,或者我的理解在某些地方存在缺陷。
我为什么要这样做?
我想“安全地”使用 snprintf,即避免字符串截断。这个想法是在使用 snprintf 之前确定字符串大小。这意味着使用它两次。一旦锻炼了大小,然后分配适当的内存以再次使用 snprintf。当然,任何 printf 函数都需要可变数量的输入。所以想用 vsnprintf 创建一个可变参数函数来完成上述操作。
我知道仍然存在检查传递的原始字符串是否不太长并且不会导致字符串截断的问题。但对为什么 vsnprintf 没有按预期工作感到困惑
【问题讨论】:
-
by avoiding string truncation但你的缓冲区是 long_string 256 个字符长,所以无论如何它都会被截断。或者,strcpy(buffer, bufferString);将无效。malloc (n - 1);为什么分配少一个字符?而且,对于您的错误:printf("m = %d\n", m);您正在打印变量m,而不是n。 -
在编写问题代码时出现了一些拼写错误。对此很陌生。道歉。
malloc (n -1)是一个错误。感谢您指出这一点。 -
n中的malloc (n - 1);是什么?哪种类型?它在哪里分配?为什么是-1?
标签: c variadic-functions variadic