C 不带va_列表的自定义printf

C 不带va_列表的自定义printf,c,C,我试图创建printf的简化版本,但没有使用va_list、va_start、va_arg和va_end 我最初的想法是: 作废我的打印字符*格式 然后,检查该格式,并计算%参数的数量,以了解有多少变量被传递到我的函数。从那里开始,我考虑根据有多少个参数创建一个缓冲区,然后组合,然后使用write最终输出它们 有没有更好的方法来解决这个问题?我的计划会遇到问题吗 任何帮助都将不胜感激 我的一些头脑风暴代码是: // Count arguments int cnt_s, cnt_c, cnt_d,

我试图创建printf的简化版本,但没有使用va_list、va_start、va_arg和va_end

我最初的想法是:

作废我的打印字符*格式

然后,检查该格式,并计算%参数的数量,以了解有多少变量被传递到我的函数。从那里开始,我考虑根据有多少个参数创建一个缓冲区,然后组合,然后使用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++;
            }
    }
}
您需要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和朋友们以便携方式为你做的事情。