0

我正在尝试创建 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++;
            }
    }
}
4

2 回答 2

4

需要 va_list, va_start, va_arg, 和va_end来访问由...

除非你想用void*和工会----- UGH!

于 2013-03-14T21:06:15.223 回答
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 魔法。

于 2014-02-28T00:34:47.357 回答