如何在 C++ 中解析包含 -0x1.0c7474fp+8 形式的十六进制文件?
How to parse file containing hexadecimals in the form -0x1.0c7474fp+8 in c++?
我正在尝试解析包含 十六进制数 的文件 data.txt
,格式为 -0x1.0c7474fp+8
:
-0x1.e51b67p+0 0x1.0b18ef5p+8 0x1.9c6075p+8 -0x1.190d44p+4
-0x1.e4f7838p+0 0x1.0b6446dp+8 0x1.9d779b8p+8 -0x1.16436ap+3
-0x1.e4555bp+0 0x1.0b6d446p+8 0x1.9e28c4ap+8 -0x1.1f8b0ep+3
-0x1.e3b9598p+0 0x1.0b7982cp+8 0x1.9edf5f8p+8 -0x1.f80bc6p+2
-0x1.e2f5896p+0 0x1.0b70bd7p+8 0x1.9f75c6ap+8 -0x1.07390ep+3
-0x1.e21d2dep+0 0x1.0b5961cp+8 0x1.9fef6e6p+8 -0x1.031012p+3
-0x1.e225b96p+0 0x1.0bbc104p+8 0x1.a12c75cp+8 -0x1.06951cp+3
-0x1.e17ec4cp+0 0x1.0bc35b7p+8 0x1.a1de5a6p+8 -0x1.25f138p+3
-0x1.e0e7f36p+0 0x1.0c140edp+8 0x1.a300c22p+8 -0x1.417644p+3
-0x1.e0e7e0ap+0 0x1.0c7474fp+8 0x1.a43f084p+8 -0x1.359f22p+3
-0x1.e076e6cp+0 0x1.0c93aebp+8 0x1.a50efaap+8 -0x1.00e406p+4
-0x1.e1c339cp+0 0x1.0ec7d62p+8 0x1.ab2777p+8 -0x1.1b6134p+3
-0x1.e0614eap+0 0x1.0e669d1p+8 0x1.ab301b8p+8 -0x1.6a997cp+2
-0x1.e01577p+0 0x1.0e9f2e5p+8 0x1.ac33c36p+8 -0x1.62eb42p+2
-0x1.de237dcp+0 0x1.0df5506p+8 0x1.abd2c42p+8 -0x1.8951c2p+2
我写了这段 c++
代码但没有成功:
#include <iostream>
#include <fstream>
int main()
{
float a, b, c, d;
std::ifstream ifs("data.txt");
int n = 0;
while(ifs >> std::hex >> a
>> std::hex >> b
>> std::hex >> c
>> std::hex >> d)
{
std::cout << a << " "
<< b << " "
<< c << " "
<< d << std::endl;
++n;
}
std::cout << "n=" << n << std::endl;
return 0;
}
编辑:我尝试使用 std::hexfloat
,但它仍然无法使用 gcc
,如图 in this example 所示。
-0x1.e51b67p+0
gobble-de-gook 是 std::hexfloat
的输出,是 C++ 11 标准修订版中 C++ 标准库的补充。
如果替换
while(ifs >> std::hex >> a
>> std::hex >> b
>> std::hex >> c
>> std::hex >> d)
和
while(ifs >> std::hexfloat >> a
>> std::hexfloat >> b
>> std::hexfloat >> c
>> std::hexfloat >> d)
并且您的编译器支持 C++11 和 hexfloat
(G++ 在这方面有点滞后)您应该可以开始了。
编辑:G++ 在 headers 中包含 std::hexfloat
时比较滞后。不幸的是,截至今天,GCC 8.2 对 std::hexfloat
的支持不完整且无法正常工作。此答案不适用于提问者。
编辑2:我活该为此倒在我的剑上,幸好我没有剑。在我着迷地研究为什么这在 C++ 中不起作用并试图找到一种礼貌的方式使它在 C++ 中起作用时,我完全忘记了这个在 C 中工作得很好的事实。
既然std::hexfloat
在整理C++标准的写法,那么就跟着Git-R完成吧!原理,用C,把它包在一个函数里,方便以后换成惯用的C++。
#include <cstdio>
#include <iostream>
int main()
{
float a, b, c, d;
FILE *f = fopen("data.txt", "r");
if (f == NULL)
{
std::cerr << "Unable to open file."
return -1;
}
int n = 0;
while(fscanf(f, "%a %a %a %a", &a, &b, &c, &d) == 4)
{
std::cout << a << " "
<< b << " "
<< c << " "
<< d << std::endl;
++n;
}
std::cout << "n=" << n << std::endl;
return 0;
}
似乎 GCC 仍然无法正确处理 "hexFloat",查看 gcc 错误跟踪器:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59987
这个简单的替代解决方案怎么样?
#include <iostream>
int main() {
const char *data = "-0x1.e51b67p+0 0x1.0b18ef5p+8 0x1.9c6075p+8 -0x1.190d44p+4 -0x1.e4f7838p+0 0x1.0b6446dp+8 0x1.9d779b8p+8 -0x1.16436ap+3";
char *end;
for (float f = strtof(data, &end); data != end; f = strtof(data, &end))
{
data = end;
if (errno == ERANGE){
printf("range error, got ");
errno = 0;
}
printf("%a\n", f);
}
return 0;
}
我正在尝试解析包含 十六进制数 的文件 data.txt
,格式为 -0x1.0c7474fp+8
:
-0x1.e51b67p+0 0x1.0b18ef5p+8 0x1.9c6075p+8 -0x1.190d44p+4
-0x1.e4f7838p+0 0x1.0b6446dp+8 0x1.9d779b8p+8 -0x1.16436ap+3
-0x1.e4555bp+0 0x1.0b6d446p+8 0x1.9e28c4ap+8 -0x1.1f8b0ep+3
-0x1.e3b9598p+0 0x1.0b7982cp+8 0x1.9edf5f8p+8 -0x1.f80bc6p+2
-0x1.e2f5896p+0 0x1.0b70bd7p+8 0x1.9f75c6ap+8 -0x1.07390ep+3
-0x1.e21d2dep+0 0x1.0b5961cp+8 0x1.9fef6e6p+8 -0x1.031012p+3
-0x1.e225b96p+0 0x1.0bbc104p+8 0x1.a12c75cp+8 -0x1.06951cp+3
-0x1.e17ec4cp+0 0x1.0bc35b7p+8 0x1.a1de5a6p+8 -0x1.25f138p+3
-0x1.e0e7f36p+0 0x1.0c140edp+8 0x1.a300c22p+8 -0x1.417644p+3
-0x1.e0e7e0ap+0 0x1.0c7474fp+8 0x1.a43f084p+8 -0x1.359f22p+3
-0x1.e076e6cp+0 0x1.0c93aebp+8 0x1.a50efaap+8 -0x1.00e406p+4
-0x1.e1c339cp+0 0x1.0ec7d62p+8 0x1.ab2777p+8 -0x1.1b6134p+3
-0x1.e0614eap+0 0x1.0e669d1p+8 0x1.ab301b8p+8 -0x1.6a997cp+2
-0x1.e01577p+0 0x1.0e9f2e5p+8 0x1.ac33c36p+8 -0x1.62eb42p+2
-0x1.de237dcp+0 0x1.0df5506p+8 0x1.abd2c42p+8 -0x1.8951c2p+2
我写了这段 c++
代码但没有成功:
#include <iostream>
#include <fstream>
int main()
{
float a, b, c, d;
std::ifstream ifs("data.txt");
int n = 0;
while(ifs >> std::hex >> a
>> std::hex >> b
>> std::hex >> c
>> std::hex >> d)
{
std::cout << a << " "
<< b << " "
<< c << " "
<< d << std::endl;
++n;
}
std::cout << "n=" << n << std::endl;
return 0;
}
编辑:我尝试使用 std::hexfloat
,但它仍然无法使用 gcc
,如图 in this example 所示。
-0x1.e51b67p+0
gobble-de-gook 是 std::hexfloat
的输出,是 C++ 11 标准修订版中 C++ 标准库的补充。
如果替换
while(ifs >> std::hex >> a
>> std::hex >> b
>> std::hex >> c
>> std::hex >> d)
和
while(ifs >> std::hexfloat >> a
>> std::hexfloat >> b
>> std::hexfloat >> c
>> std::hexfloat >> d)
并且您的编译器支持 C++11 和 hexfloat
(G++ 在这方面有点滞后)您应该可以开始了。
编辑:G++ 在 headers 中包含 std::hexfloat
时比较滞后。不幸的是,截至今天,GCC 8.2 对 std::hexfloat
的支持不完整且无法正常工作。此答案不适用于提问者。
编辑2:我活该为此倒在我的剑上,幸好我没有剑。在我着迷地研究为什么这在 C++ 中不起作用并试图找到一种礼貌的方式使它在 C++ 中起作用时,我完全忘记了这个在 C 中工作得很好的事实。
既然std::hexfloat
在整理C++标准的写法,那么就跟着Git-R完成吧!原理,用C,把它包在一个函数里,方便以后换成惯用的C++。
#include <cstdio>
#include <iostream>
int main()
{
float a, b, c, d;
FILE *f = fopen("data.txt", "r");
if (f == NULL)
{
std::cerr << "Unable to open file."
return -1;
}
int n = 0;
while(fscanf(f, "%a %a %a %a", &a, &b, &c, &d) == 4)
{
std::cout << a << " "
<< b << " "
<< c << " "
<< d << std::endl;
++n;
}
std::cout << "n=" << n << std::endl;
return 0;
}
似乎 GCC 仍然无法正确处理 "hexFloat",查看 gcc 错误跟踪器:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59987
这个简单的替代解决方案怎么样?
#include <iostream>
int main() {
const char *data = "-0x1.e51b67p+0 0x1.0b18ef5p+8 0x1.9c6075p+8 -0x1.190d44p+4 -0x1.e4f7838p+0 0x1.0b6446dp+8 0x1.9d779b8p+8 -0x1.16436ap+3";
char *end;
for (float f = strtof(data, &end); data != end; f = strtof(data, &end))
{
data = end;
if (errno == ERANGE){
printf("range error, got ");
errno = 0;
}
printf("%a\n", f);
}
return 0;
}