C 不带va_列表的自定义printf
我试图创建printf的简化版本,但没有使用va_list、va_start、va_arg和va_end 我最初的想法是: 作废我的打印字符*格式 然后,检查该格式,并计算%参数的数量,以了解有多少变量被传递到我的函数。从那里开始,我考虑根据有多少个参数创建一个缓冲区,然后组合,然后使用write最终输出它们 有没有更好的方法来解决这个问题?我的计划会遇到问题吗 任何帮助都将不胜感激 我的一些头脑风暴代码是:C 不带va_列表的自定义printf,c,C,我试图创建printf的简化版本,但没有使用va_list、va_start、va_arg和va_end 我最初的想法是: 作废我的打印字符*格式 然后,检查该格式,并计算%参数的数量,以了解有多少变量被传递到我的函数。从那里开始,我考虑根据有多少个参数创建一个缓冲区,然后组合,然后使用write最终输出它们 有没有更好的方法来解决这个问题?我的计划会遇到问题吗 任何帮助都将不胜感激 我的一些头脑风暴代码是: // Count arguments int cnt_s, cnt_c, cnt_d,
// Count arguments
int cnt_s, cnt_c, cnt_d, cnt_u, cnt_x;
for (; *format; format++) {
switch(format[0]) {
case '%':
switch(format[1]) {
case 'd':
cnt_d++;
}
}
}
您需要va_list、va_start、va_arg和va_end来访问由
除非你想使用void*和unions——啊 我能想到的最好的方法是这样做:这可能是不安全的,那就是获取格式字符串的地址并从中递增以找到参数 下面是我拼凑的一个工作示例,它假设实现了其他打印功能
int my_printf(char *format, ...) {
void *beg = &format;
int i;
beg += sizeof(char*);
for (i = 0; i < strlen(format); i++) {
if (format[i] == '%') {
switch (format[i+1]) {
case 's':
print_s(*((char**)beg));
beg += sizeof(char*);
break;
case 'd':
print_d(*((int*)beg));
beg += sizeof(int);
break;
case 'f':
print_f(*((float*)beg));
beg += sizeof(float);
break;
}
i++;
} else {
putchar(format[i]);
}
}
}
如果您没有提供足够的参数,这可能会导致一些意外的副作用,并且可能需要进行一些调整。但这就是想法
说明:
这是因为所有函数参数都按顺序推送到堆栈上。因此,由于第一个参数是格式字符串,因此您可以根据所需参数获取其地址和增量,以直接访问堆栈上的参数,而无需任何VA_ARGS魔法。您需要VA_list、VA_start、VA_arg、,我想直接从内存中访问它们。除了。。。然后呢?那是个可笑的坏主意。你为什么要试图绕过访问变长参数数组的标准方法?这不适用于任何实际应用。将一个联合数组传递给你的函数void*是一个大脑屁。。。但你真的想要瓦阿格和朋友!如果我能使用va_列表什么的,我会的,但在这种情况下我不能。将使用my_printformat、arg1、arg2、arg3等调用该函数。我如何在不使用VAU列表的情况下获取这些参数?我正在考虑使用format变量,该变量是作为起始内存位置提供的,然后计算format中列出的arg的数量,然后使用该变量,从起始位置format跳转内存并获取每个变量。有更好的方法吗?我的打印格式,intval,我的打印格式,doubleval,我的打印格式,intval1,intval2,intval3,doubleval,intval4…@Pat:你所描述的正是va_start和朋友们以便携方式为你做的事情。