简体   繁体   English

从标准输入读取双数,使用 C read()

[英]Read a double number from stdin, with C read()

According to the Linux manual ,根据Linux手册

#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);

attempts to read up to count bytes from file descriptor fd into the buffer starting at buf.尝试将文件描述符 fd 中的 count 个字节读入缓冲区,从 buf 开始。

I am writing a C program that uses "read" (instead of scanf) to read a double from stdin.我正在编写一个 C 程序,它使用“读取”(而不是 scanf)从标准输入读取双精度值。 Below is what I get.下面是我得到的。 I typed inputs such as 42.0, 47.9, etc from the console.我从控制台输入了 42.0、47.9 等输入。 It turns out that the program produces random outputs.事实证明,该程序会产生随机输出。 Can anyone help?任何人都可以帮忙吗?

#include <stdio.h>
#include <unistd.h>

int main(){
    double x;
    read(0, &x, sizeof(x));
    printf ("Results = %g\n", x);
}

Input on standard input (please use STDIN_FILENO instead of the "magic number" 0 ) is usually text .标准输入上的输入(请使用STDIN_FILENO而不是“幻数” 0 )通常是text

You attempt to read the input as a raw binary representation of the value.您尝试将输入读取为值的原始二进制表示。

Unless you know that the input will be in raw binary form (for example from redirection of a binary file or from a pipe where the other end is writing raw binary data) I suggest you read into a character buffer, make sure the buffer is null-terminated (you have to do it yourself, the position is what read return if successful), and use eg sscanf or strtod to convert the string.除非您知道输入将采用原始二进制形式(例如来自二进制文件的重定向或来自另一端写入原始二进制数据的管道)我建议您读入字符缓冲区,确保缓冲区为空-终止(你必须自己做,位置是read成功时返回的内容),并使用例如sscanfstrtod转换字符串。

As the manual says, attempts to read up to count bytes from file descriptor fd and that means for a double for example to read sizeof (double) bytes with the internal format representation of a double value.作为手册说,尝试读取到计从文件描述符fd字节和用于一个double例如读取sizeof (double)带的内部格式表示字节double值。 As it says it reads bytes, those bytes can be generated by a corresponding write(2) of a double value, but are only understandable by the machine, so entering 24.2 is not valid, as that is a string representation of a number in ascii decimal form.正如它所说的读取字节,这些字节可以通过double值的相应write(2)生成,但只能由机器理解,因此输入24.2无效,因为它是 ascii 中数字的字符串表示十进制形式。

There's a standard binary representation for internal use on extended use, described in the IEEE-752 standard. IEEE-752 标准中描述了用于内部扩展使用的标准二进制表示。 It describes internal binary format representations for float , double and extended long doubles (128bit representation of a floating point number, normally not used in current architectures, but only a small set) If you know it, probably you can produce the exact representation needed to be able to input correctly a specific number.它描述了floatdouble扩展 long doubles 的内部二进制格式表示( float 128 位表示,通常不在当前架构中使用,但只是一小部分)如果您知道,可能您可以生成所需的确切表示能够正确输入特定数字。 You should read that document in order to understand why the sequence of chars 2 , 4 , .您应该阅读该文档以了解为什么字符24. , 2 , that form the string 24.2 is not the same as the internal binary representation of that number, which is what is written by write(2) . , 2 ,形成字符串24.2与该数字的内部二进制表示不同,这是write(2)

Try to write(2) that first, with:尝试先write(2) ,用:

double number = 3.1415926535897932;
write(1, &number, sizeof number);

and see what happens in your output.看看你的输出会发生什么。 Next try to filter up with a hex reader, as in接下来尝试使用十六进制阅读器进行过滤,如

$ new_program | hd

and you'll see the exact values of the bytes that pi produces.你会看到 pi 产生的字节的确切值。 Then, try to feed that to your original program, as in然后,尝试将其提供给您的原始程序,如

$ new_program | your_original_program

and print them again with并再次打印它们

read(0, &my_double, sizeof my_double);
printf("%g", my_double);

you'll see that what was read is what you wrote, but the binary representation of a double value is, in general, misunderstandable for humans (well, there's people so used to binary that understand hex dumps up to this level, but I'm not one of them)您会看到读取的内容就是您编写的内容,但是通常而言, double值的二进制表示对于人类来说是无法理解的(嗯,有些人习惯于二进制,可以理解到这个级别的十六进制转储,但是我”我不是其中之一)

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

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