你能从C中的空格*打印F值吗

你能从C中的空格*打印F值吗,c,pointers,void,C,Pointers,Void,好的,我正在尝试这样做,但它不起作用,因为我没有取消指针的引用。。。有没有一种方法可以在不为类型生成switch语句的情况下执行此操作 typedef struct { char *ascii_fmtstr; int len; int (*deserializer)(void *in, const char *ascii); int (*serializer)(const void *in, char *ascii); } FORMAT; const FORMA

好的,我正在尝试这样做,但它不起作用,因为我没有取消指针的引用。。。有没有一种方法可以在不为类型生成switch语句的情况下执行此操作

typedef struct
{
    char *ascii_fmtstr;
    int len;
    int (*deserializer)(void *in, const char *ascii);
    int (*serializer)(const void *in, char *ascii);
} FORMAT;

const FORMAT formats[]=
{
    {"%d\n",    2/2}        //Int
    ,{"%s\n",   STRSIZE/2}  //String
    ,{"%.4f\n", 4/2}        //Float
    ,{"%lld",   4/2}        //Long-Long
    ,{"%s\n",   STRSIZE/2}  //Time
};

typedef struct {
    int fmtindex;
    void * vp;
} JUNK;

float f = 5.0f;
int i=1;
char foo[]="bar";

JUNK j[] = {
     {2, &f}
     ,{0, &i}
     ,{1, foo}};

void dump(void)
{
    int i;
    for(i=0;i<2;i++)
        printf(formats[j[i].fmtindex].ascii_fmtstr, j[i].vp);

}
typedef结构
{
字符*ascii_fmtstr;
内伦;
int(*反序列化器)(void*in,const char*ascii);
int(*序列化程序)(常量void*in,char*ascii);
}格式;
常量格式[]=
{
{“%d\n”,2/2}//Int
,{“%s\n”,STRSIZE/2}//字符串
,{“%.4f\n”,4/2}//浮点
,{“%lld”,4/2}//Long
,{“%s\n”,STRSIZE/2}//时间
};
类型定义结构{
int-fmtindex;
void*vp;
}垃圾;
浮球f=5.0f;
int i=1;
char foo[]=“bar”;
垃圾j[]={
{2,&f}
,{0,&i}
,{1,foo};
作废转储(作废)
{
int i;

对于(i=0;i您可以使用类似于
%p
的内容打印指针本身,但是,如果要打印指针指向的内容,您需要告诉它它是什么:

printf ("%d", *((int*)myVoidPtr));

不允许仅仅因为编译器不知道它指向什么而取消引用
void*

这样想:
任何
指针都只指向一个内存位置。但是指针的
类型决定了
之后要解释/考虑的
字节数。If它是
char*
然后(取决于系统)如果是
int*
4个字节,则解释1个字节。但是
void*
具有
无类型
。因此,由于这个简单的原因,您不能在C中取消引用
void
指针。但是您可以使用
printf()中的
%p
格式说明符打印出它指向的地址
并将该
void
指针作为参数传递

printf("The address pointed by void pointer is %p",void_ptr); //Correct

printf("The address pointed by void pointer is %p",(void*)int_ptr);//Correct
假设
int_ptr
是一个整数指针,而
void_ptr
是一个空指针

printf("Value at address pointed by void pointer is %d",*void_ptr);// Wrong

printf("Value at address pointed by void pointer is %d",*(void*)int_ptr);//Wrong

不清楚您的真正目标是什么。是的,有一些方法可以根据数据类型打印。基本上,这个想法是创建您自己的打印功能

但是仅仅提供指针是不够的。在任何情况下,您都需要提供指针及其类型

假设我们有一个函数
myprint

myprint("%m %m %m %i", TYPE_INT, &i, TYPE_FLOAT, &f, TYPE_STRING, foo, 10);
可能是调用。
myprint
是一个varargs函数,它需要重建格式字符串和参数,然后可以调用real
printf

如果只使用堆变量,则变量的类型可以通过一些技巧与数据一起存储(提示:检查
malloc
如何存储块大小)。这将使附加参数成为超级参数


还有其他解决方案,但如果不了解您的真正目标和确切条件,就不可能提出好的建议。

我认为
printf
及其朋友(fprintf等)只能取消引用
char*
,而这将被解释为c字符串

实际上,您可以自己编写这样的函数,因为您将告诉您的函数如何使用格式标志取消引用
void*

您还可以将指向所需解引用函数的指针作为第三个值添加到
格式中,该函数将以
void*
作为参数,并返回值而不是指针。
因此,您需要为您在格式中使用的每种类型编写一个函数,并将每个函数正确地分配给每种格式。

似乎您正在使用
void*
作为廉价的
union
。这是一个非常糟糕的主意。我想您会发现
union
enum
switch
结合使用在C语言中,你可以在
#ifdef开关中找到
开关
#else
,在
#else
中找到无开关版本

#include <stdio.h>

struct object {
    enum type {
        d=0,
        s=1,
        f=2,
        lld=3,
        time=4
    } type;

    union instance {
        int d;
        char *s;
        float f;
        long long lld;
        char *time;
    } instance;
};

#ifdef SWITCH
void print_object(struct object *o) {
    switch (o->type) {
        case d: printf("%d", o->instance.d); break;
        case s: printf("%s", o->instance.s); break;
        case f: printf("%f", o->instance.f); break;
        case lld: printf("%lld", o->instance.lld); break;
        case time: printf("%s", o->instance.time); break;
    };
}
#else
void print_d(struct object *o);
void print_s(struct object *o);
void print_f(struct object *o);
void print_lld(struct object *o);
void print_time(struct object *o);

void print_object(struct object *o) {
    void (*print_functions[])(struct object *) = {
         [d] = print_d,
         [s] = print_s,
         [f] = print_f,
         [lld] = print_lld,
         [time] = print_time
    };

    print_functions[o->type](o);
}

void print_d(struct object *o) { printf("%d", o->instance.d); }
void print_s(struct object *o) { printf("%s", o->instance.s); }
void print_f(struct object *o) { printf("%f", o->instance.f); }
void print_lld(struct object *o) { printf("%lld", o->instance.lld); }
void print_time(struct object *o) { printf("%s", o->instance.time); }
#endif

int main(void) {
    struct object o = { .type = d,                /* type: int */
                        .instance = { .d = 42 }   /* value: 42 */ };

    print_object(&o);
    return 0;
}
#包括
结构对象{
枚举类型{
d=0,
s=1,
f=2,
lld=3,
时间=4
}类型;
联合实例{
int d;
char*s;
浮动f;
朗朗法学博士;
字符*时间;
}实例;
};
#ifdef开关
无效打印对象(结构对象*o){
开关(o->类型){
案例d:printf(“%d”,o->instance.d);break;
案例s:printf(“%s”,o->instance.s);break;
案例f:printf(“%f”,o->instance.f);break;
案例lld:printf(“%lld”,o->instance.lld);break;
案例时间:printf(“%s”,o->instance.time);中断;
};
}
#否则
无效打印(结构对象*o);
无效打印(结构对象*o);
无效打印(结构对象*o);
无效打印(结构对象*o);
无效打印时间(结构对象*o);
无效打印对象(结构对象*o){
void(*打印函数[])(结构对象*)={
[d] =打印,
[s] =打印,
[f] =打印,
[lld]=打印lld,
[时间]=打印时间
};
打印功能[o->type](o);
}
void print_d(结构对象*o){printf(“%d”,o->instance.d);}
void print_s(结构对象*o){printf(“%s”,o->instance.s);}
void print_f(结构对象*o){printf(“%f”,o->instance.f);}
void print_lld(struct object*o){printf(“%lld”,o->instance.lld);}
void print_time(结构对象*o){printf(“%s”,o->instance.time);}
#恩迪夫
内部主(空){
结构对象o={.type=d,/*type:int*/
.instance={.d=42}/*值:42*/};
打印对象(&o);
返回0;
}

这是正确的,但与OP的问题无关。因为他已经以该格式传递了类型信息,
printf
拥有取消引用指针本身所需的所有信息(如果存在这种格式的话)。(事实上,这正是
scanf
的工作方式,它的所有参数都是指针。)没有,但这是一个接口问题,不是他的方法的根本缺陷。
我不认为printf和它的朋友可以从指针上解除引用,除了char*,这将被解释为sting。
我不理解你的意思。请详细说明@