繁体   English   中英

可变参数函数和va_arg:使要打印的类型可变

[英]Variadic function and va_arg : variabilizing the type to be printed

我正在尝试重新编码printf函数,因此我需要使用va_arg因为printf是可变参数。

问题是,当我想打印出my_printf的参数时,如果采用这两种基本my_printf ,它们可以是%iint )或%schar * )。

因此,当我浏览va_list ap ,我尝试在va_arg函数中放置一个变量,以便可以更改要写入的类型,如下所示:

char *str = NULL;
str = ft_set_my_types(flags[cur_arg]);          
ft_putstr(va_arg(ap, str));

与我的函数ft_set_my_types类似:

char *ft_set_my_types(char *flags)
{
    char **tab = NULL;

    tab = ft_alloc_mem2(2, 15); /* this function malloc a tab */
    char a = 65;

     /* the example here is only with two types of variables */
     /* I am sending flags %s in my example which correspond to "char *" */

    tab['s'] = "char *";
    tab['d'] = "int ";

    size_t len = ft_strlen(flags) - 1;
    while (a < 123)
    {
        if (a == flags[len])
            break ;
        else
            a++;
    }
    return (tab[a]);
}

“ char *标志”是介于“%”和my_printf的标志(包括)之间的my_printf

问题是:当我编译它时,我的tab ['s]不能理解为char *而不能理解为“ char *”,因此出现以下错误:

ft_print.c:63:25: error: unknown type name 'str'
                        ft_putstr(va_arg(ap, str));
                                             ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/7.0.2/include/stdarg.h:35:50: note:
      expanded from macro 'va_arg'
#define va_arg(ap, type)    __builtin_va_arg(ap, type)
1 error generated.

您能帮我弄清楚如何在此va_arg函数中插入变量*str吗?

C是静态类型的。 所有数据类型都是在编译时确定的。 您不能通过调用函数来获取声明的数据类型。

相反,要处理直到运行时才知道其类型的可变参数,您必须基于选定的数据类型,通过switch语句或if / else if / else嵌套分支。 在每个替代方案中,使用va_arg宏获取参数,并使用该替代方案处理的适当静态类型。 如果愿意,您可以在助手功能中执行特定于类型的处理。

例如,

/* ... */
switch (field_code) {
    case 'i':
        do_something_with_int(va_arg(ap, int));
        break;
    case 's':
        do_something_with_string(va_arg(ap, char *));
        break;
    default:
        handle_error();
        break;
}
/* ... */

请注意, va_arg的第二个参数是类型本身,而不是其字符串表示形式。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM