使用write函数打印浮点数。

4

在以下代码中,write函数不会打印浮点数:

#include <unistd.h>

int main(){

    float f = 4.5;

    write(1,&f,sizeof float);

    return 0;
}

这将导致:
�@

鉴于:

int main(){

    char *c = "Hello world";

    write (1,c,strlen(c)+1);

    return 0;
}

按预期打印Hello world

我错过了什么?

提前致谢。


嗯,printf不是一个选项吗?还是你只是在做练习?write只会将原始二进制数据输出到屏幕上,而浮点数需要进行解释。 - zdav
printf不是一个选项,因为这将会用MIPS汇编语言编写。 - Tom
1
@Tom:函数的可用性不取决于CPU架构。 - kennytm
@Kenny 我知道,但我不想从汇编中调用C。 - Tom
@Tom:write 已经有点像 C 函数了(是的,它可能是一个内核调用,但我认为大多数内核都有 printf)。 - kennytm
@Kenny。是的,我知道。从汇编语言中,我直接通过系统调用调用sys_write。不想从我的汇编代码中调用任何用户空间的C代码。如果它在内核中,我可以接受。谢谢。 - Tom
5个回答

4

write 输出浮点数的二进制表示中的字节。这些字节甚至不总是对应于可读字符,更别提数字本身的文本表示了。

我猜你想将数字转换为人类可读的文本。这就是 printf 的作用:

printf("%f", f);

是的,但我不能使用printf,必须使用write。所以我想我必须将它们转换为字节? - Tom
1
你可以使用sprintf,但那只是愚蠢的做法。为什么不使用write呢? - Lukáš Lalinský
因为我必须将其转换为汇编语言,使用SYS_WRITE。 - Tom
最终我避免了从汇编语言中写入,并将浮点值插入到一个外部数组中。然后从C中打印它们。 - Tom
如果这与C标准库相关联,您也可以从汇编中调用printf。但我猜从C中调用会更容易 :) - Thomas

3
将浮点数转换为字符串并不是一个简单的问题。即使是微软公司也会犯错,例如著名的Excel 2007 bug。您应该使用库函数,如snprintf(3)将浮点数转换为字符串,然后可以使用write(2)写出该字符串:
float f = 4.5f;
char buf[64];
snprintf(buf, sizeof(buf), "%g", f);
write(1, buf, strlen(buf));

谢谢,这给了我一个好主意。 - Tom
最终我避免了从汇编语言中写入,并将浮点值插入到一个外部数组中。然后从C中打印它们。 - Tom

0

使用write会引入字节序的依赖性。因此,当您读取文件时,可能需要反转字节顺序。

否则,您的代码完全正常。您是否尝试编写另一个程序以相同的方式读取并比较结果?

使用write的整个目的是避免转换为文本。

int main(){

    float f;

    read(0,&f,sizeof(float) );
    printf( "%f", (double) f );

    return 0;
}

在 shell 中执行

write_test | read_test

0

您可以使用已过时的函数gcvt()将浮点数转换为字符串:

#include <stdlib.h>
#include <stdio.h>
int main() { char buffer[11];
gcvt(3.1425, 3, buffer); buffer[10]=0;
write(1, buffer,strlen(buffer)+1);
return 0; }

但是,最好使用snprintf()。


0

寻找一个ftoa的实现。正如其他人所提到的,从浮点数转换为字符串表示并不是一项简单的任务。试图从汇编语言中进行这样的转换将是一个相当大的挑战。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接