我正在尝试创建printf()的简化版本,但不使用va_list,va_start,va_arg和va_end。
我最初的想法是:
void my_printf(char * format,...);
然后,浏览格式,并计算%(参数)的数量,以找出传递给我的函数的变量数量。从那里开始,我考虑根据有多少个参数创建一个缓冲区,然后组合然后使用write()最终输出它们。
有没有更好的方法来解决这个问题?我的计划会遇到问题吗?
非常感谢任何帮助。
我的一些头脑风暴代码是:
// 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++;
}
}
}
答案 0 :(得分:3)
您需要 va_list
,va_start
,va_arg
和va_end
才能访问...
指定的参数
除非您想使用void*
和工会----- UGH!
答案 1 :(得分:3)
我能想到的最好的方法(注意:这可能是不安全的)是获取格式字符串的地址并从中增加以查找参数。
下面是我一起攻击的一个工作示例(假设实现了其他打印功能)
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魔法。