Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 省略号函数参数的大小(字节)_C++_C_Printf_Variadic Functions - Fatal编程技术网

C++ 省略号函数参数的大小(字节)

C++ 省略号函数参数的大小(字节),c++,c,printf,variadic-functions,C++,C,Printf,Variadic Functions,我有一个功能: static int myprintf(const char* fmt, ...) 我想知道所有myprintf参数的字节大小,如果它们被打印到缓冲区。 我需要动态分配一个数组,我可以将参数打印到该数组中(使用sprinf或\u vsprinf) 例如,在32位操作系统中,对于myprintf(“%d%c”,10,'a'); myprintf参数的大小为5 我试着像这样实现它: va_list ap; va_start(ap, fmt); myArgSize(ap); 有

我有一个功能:

static int myprintf(const char* fmt, ...)
我想知道所有myprintf参数的字节大小,如果它们被打印到缓冲区。 我需要动态分配一个数组,我可以将参数打印到该数组中(使用
sprinf
\u vsprinf
) 例如,在32位操作系统中,对于myprintf(“%d%c”,10,'a'); myprintf参数的大小为5

我试着像这样实现它:

va_list ap;

va_start(ap, fmt);

myArgSize(ap);
有人能建议如何实现myArgSize吗

我被告知要试试这样的东西

char c;
int len = ::_vsnprintf(&c, 1, fmt, ap);
由于写入了超过一个字节,因此无法工作。 但可能有一些解决办法


谢谢

那么。。。关于参数类型和顺序的唯一信息在第一个参数中;这就是为什么它是必需的

对于类
printf()
-like函数,您需要逐步遍历格式化字符串,解析每个
%
-code,并添加相应类型的大小。这不是小事。记住要处理像
%hd
这样的事情,它需要
而不是
int
。此外,将值传递给变量函数时也会发生转换。

您可以使用sizeof(type_name)并使用for循环遍历所有参数, type_name是int、float、long等任意c数据类型。。
然后添加所有字节,

您可以使用
vasprintf
将所有格式设置到适当大小的缓冲区中,缓冲区将分配给您(您必须
释放

或者,可以使用
vsnprintf
获取字符串的长度
printf
将打印:

int n = vsnprintf(NULL, 0, fmt, args);

这是因为如果有足够的空间,它将返回要打印的字节数。在这种情况下,它不能打印任何内容,但仍然返回数字。

尽管您的问题主要是关于传递给triadic函数的参数的大小,但在我看来,您实际上对输出缓冲区需要有多大感兴趣。请尝试以下操作:

va_list ap;

va_start(ap, fmt);

int len = ::vsnprintf( NULL, 0, fmt, ap);
if (len < 0) abort();

char* buffer = (char*) malloc( len + 1);
if (!buffer) abort();

::vsnprintf( buffer, len+1, fmt, ap);

va_end();
va_列表ap;
va_启动(ap、fmt);
int len=::vsnprintf(NULL,0,fmt,ap);
如果(len<0)中止();
char*buffer=(char*)malloc(len+1);
如果(!buffer)中止();
::vsnprintf(缓冲区、len+1、fmt、ap);
va_end();

但是,如果您的平台没有符合C99标准的
vsnprintf()
(例如,MSVC),则必须进行一些调整。对于MSVC,您可以尝试通过猜测(可能是
strlen(fmt)+1+(10*百分比符号的数量)
,或者从一个应该覆盖99%案例的大小开始-可能是
200
),然后增加猜测,直到它起作用。或者您可以尝试类似的操作。

您说“myprintf参数的大小为5”。但如果我理解您的要求,则不会,堆栈上有8个字节。4表示int,4表示ehm,另一个int。在32位系统上,除浮点值外,可变函数中的所有值均为4字节
float
double
是8个字节。注意长双精度。您对用于字符串表示的字符数感兴趣,还是对用于值本身的字节数感兴趣?这些是完全不同的,例如,当以十进制打印时,4字节整数可能需要1到10个字符。@MrLister:WTF您吸烟吗<代码> 'A' < /Cord>是一个字符,在C++中,通过<代码> SigeOS/<代码>的定义,具有<代码> siZeOf(char)=1 。在大多数机器上,
char
是1字节。@MrLister:这不完全取决于实现吗?例如,他可以使用自定义调用约定,或者编译器可以内联调用。我不认为他指的是“用于调用函数的堆栈的超级依赖于实现的大小”,不管怎样,它都会比参数大。参数本身只有一个大小。任何给定的实现都可能希望使用比堆栈上更多的空间,这一事实与此无关。我很确定将错误的格式说明符传递给
printf
是完全错误的,因此您的示例没有任何意义。@解开:一个涉及
::func()
语法的C问题?不会发生的@米凯瑟莫尔:这是一个理性的论点,可能会影响结果。毕竟,我想这取决于你如何看待“论点”。雅科夫:是的,我不得不重新编辑。下次再小心一点。除了他的问题只被标记为C++@DeadMG,而不是现在。。。我也不认为是我第一次找到它的时候。哦,他只是把它重新编辑了一遍?我讨厌那些不能决定自己用什么语言提问的人。编辑:其他人将其重新标记为C。它不在C中。C没有
::func()
语法。C++做的。所以必须用C++编写。@死神好点,没看到那些。我已经删掉了答案中C语言的特定部分。