printf由给定的指针和格式字符串组成.浮标问题 [英] printf by given pointer and format string. Issue with floats

查看:102
本文介绍了printf由给定的指针和格式字符串组成.浮标问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于我想跟踪一些变量以了解它们如何变化,因此我想创建一个函数,该函数根据变量的类型和指向值的指针来接收格式字符串.我希望借助格式字符串,printf可以正确确定该值.确实可以,但是有一个例外-浮点值不能正确打印.

As I want to keep track of some variables in order to see how they change, I want to create a function, which receives a format string, depending on the variable's type and a pointer to the value. I hope, that with the help of the format string, printf will properly determine the value. Actually it works, but with one exception - the float values do not print properly.

这是我的代码:

#include <stdio.h>

void pprint (char* fmtstr, void* p)
{
        printf(fmtstr,*(long double *)p);
}

int main (int argc, char **argv)
{
        char cval = 64;
        int ival = -534;
        unsigned int iuval = 535;
        float fval = 534.64;
        double dval = 53432.1;
        long double ldval = 534321234.134567;
        long long lval = -654321;
        unsigned long long luval = 7654321;

        pprint ("char: %hhd\n",&cval);
        pprint ("int: %d\n",&ival);
        pprint ("uint: %u\n",&iuval);
        pprint ("float: %f\n",&fval);
        pprint ("double: %f\n",&dval);
        pprint ("long double: %Lf\n",&ldval);
        pprint ("llong: %lld\n",&lval);
        pprint ("ullong: %llu\n",&luval);
        return 0;
}

结果是:

char: 64
int: -534
uint: 535
float: 0.000000
double: 53432.100000
long double: 534321234.134567
llong: -654321
ullong: 7654321

我们可以看到,除浮点数外,其他所有内容都可以正常打印. 但是,在对pprint函数进行了一些修改之后(将void指针投射到float上):

As we can see, everything is printed OK, except the float. However, after some modification of the pprint function (casting the void pointer to float):

printf(fmtstr,*(float*)p);

结果是:

char: 0
int: 1073741824
uint: 0
float: 534.640015
double: 0.000000
long double: 0.000000
llong: -351285912010752
ullong: 4038940431088615424

现在仅正确打印浮点值. 另一个副作用是,转换为其他任何类型都会导致成功打印尺寸较小或相同的类型. (如果我强制转换为int,它将正确打印chars,但不会打印longs).因此,强制转换为long double可以解决此问题,因为它具有最大的大小.

Now only the float value is printed properly. Another side effect is, that casting to any other type results in successful printf of types with lower or same size. (If I cast to int, it will print properly chars, but not longs). So, casting to long double solves this problem, as it hs the largest size.

但是,浮动问题仍然存在.为了打印float值,我需要将指针强制转换为float,但是别无其他.相反,当我强制转换为float时,除float之外的所有内容都会失败.取消引用是否与读取数据无关,位于指向的地址上并将其传递给printf? (将相同的指针转换为任何类型是否具有相同的地址?)然后,格式字符串可以读取"给定字节的正确格式-char,int,unsigned int等.

However, the problem with float remains. In order to print the float value, I need to cast the pointer to float, but nothing else. And the opposite: when I cast to float, everything except float fails. Isn't the dereference related to reading the data, located on the pointed address and passing it to printf? (the same pointer, casted to any type holds the same address?) Then, the format string is able to "read" the given bytes in the proper format - char, int, unsigned int, etc.

我听说,可变参数函数中的浮点值将转换为双精度.这与问题有关吗?另外,在某些情况下,我无法提供双精度值-例如,在Opengl中使用的许多变量都是浮点数(GLfloat).

I have heard, that float values in variadic functions are converted to doubles. Is that relaated to the problem? Also, in some cases I'm unable to provide the value as double - because for example many of the variables, used in Opengl are floats (GLfloat).

总而言之,我有2个问题.

In summary, I have 2 questions.

  1. 为什么浮点数与所有其他类型的行为都不同.

  1. Why floats behave different from all another types.

使用此功能会导致副作用吗?我的意思是,例如在打印int时,printf接收12个字节(sizeof(long double))作为第二个参数,但仅读取4个字节(%d"格式字符串).从这12个字节中,前4个属于我要打印的int值,接下来的8个是垃圾,printf从不读取.这有问题吗?

Can the use of this function lead to side effects? I mean, that when printing for example an int, printf receives 12 bytes (sizeof(long double)) as second parameter, but reads only 4 ("%d" format string). From these 12 bytes the first 4 belong to the int value, that I want to print, and the next 8 are junk, which are never read by printf. Is this a problem?

谢谢.

推荐答案

  1. 浮点数的行为有所不同,因为格式指定者期望使用32位大小的类型,而您要发送的是64位大小的类型.对于其他类型,您对字节序很幸运.

  1. The floats behave differently because the format specificer is expecting a 32bit sized type and you're sending it a 64 bit sized type. For the other types, you got lucky with endianness.

列出错误使用库函数的副作用是没有意义的.

Listing the side affects of using a library function incorrectly is moot.

修复代码.我会看一下vprintf()vsprintf()函数,或者更好地陈述您的设计目的,可能有比您显示的代码更简单,更可行的解决方案.

Fix the code. I'd look at the vprintf() and vsprintf() functions, or better yet, state your design purposes, there might be a simpler, more viable solution than the code you've shown.

这篇关于printf由给定的指针和格式字符串组成.浮标问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆