【问题标题】:How to read float with scientific notation from file C++?如何从文件 C++ 中读取带有科学计数法的浮点数?
【发布时间】:2012-01-24 12:03:21
【问题描述】:

我有一个格式如下的文件:

-0.0064785667 0.73900002 0.028505694 4.7858757e-39 315 218
-0.0051828534 0.73900002 0.028505694 4.6936954e-39 316 218
-0.0038818798 0.73799998 0.028467119 5.1546736e-39 317 218
-0.0025879198 0.73799998 0.028467119 5.6160217e-39 318 218
-0.0012939599 0.73799998 0.028467119 6.4461411e-39 319 218

我用这段代码读过它:

using namespace std;   

ifstream inputFile;

//Opens data file for reading.
inputFile.open(filePath.c_str());

//Creates vector, initially with 0 points.
vector<Point> data(0);
float temp_x,temp_y,temp_z,rgb=0,discard_1=0,discard_2=0;

//Read contents of file till EOF.
while (inputFile.good()){

    inputFile >> temp_x >> temp_y >> temp_z >> rgb >> discard_1 >> discard_2;

    data.push_back(Point(temp_x,temp_y,temp_z,rgb));

}

if (!inputFile.eof())
    if (inputFile.fail()) cout << "Type mismatch during parsing." << endl;
    else cout << "Unknow problem during parsing." << endl;

//Close data file.
inputFile.close();

读取科学记数法浮点数会导致类型不匹配。

如何读取所有数字,包括科学记数法浮点数?

【问题讨论】:

  • 您是否尝试将变量声明为双精度?
  • cannot reproduce这个错误。您能否提供一个显示错误的完整程序(最好通过修改我发布的示例)?
  • 尝试将 rgb 声明为 double,并且正在工作。但我希望能够直接读取浮点数......
  • 如果你尝试读取一个大于最大浮点数(大约 3.40E38)的浮点数,你会得到一个失败状态。您在此处显示的值并非如此(它们应在浮点数中读取为 0),但可以解释为什么它适用于双精度而不适用于浮点数。

标签: c++ floating-point iostream scientific-notation


【解决方案1】:

问题可能是你的while循环。永远不要使用while(inputFile.good())。使用这个:

while (inputFile >> temp_x >> temp_y >> temp_z 
                 >> rgb >> discard_1 >> discard_2) {}

This answer 到另一个问题解释了原因。您可能还对this answer 感兴趣,它提出了一个更优雅的解决方案。

【讨论】:

  • 贴出完整的代码,我会尝试你的修复,看看它是否有效。
  • @Luis:看到你的代码,我想你可能想以不同的方式解决这个问题,如我回答中第二个链接中所述。
  • @Luis:到底发生了什么?你能提供一个完整的例子吗?您是否知道即使一切正常,您的程序也会打印"Type mismatch during parsing."
  • 抱歉,更正了 else 语句,如果它到达 EOF,它将不会打印任何错误消息。只有当它没有到达 EOF 时才会打印错误消息。
  • 在您的第二个链接中,您将如何丢弃您不需要的类,例如 discard_1 和 2?
【解决方案2】:

Björn Pollex's answer 上扩展一个示例没有任何错误处理

#include <iostream>
#include <fstream>
#include <iterator>
#include <vector>

struct point
{
    double x, y, z, rgb;
};

struct point_line: public point
{
    int discard[2];
};

std::istream& operator >>(std::istream& is, point_line& in)
{
    is >> in.x >> in.y >> in.z >> in.rgb >> in.discard[0] >> in.discard[1];
    // TODO: Add your error-handlin

    return is;
}

std::ostream& operator <<(std::ostream& os, const point& out)
{
    os << " X: " << out.x
       << " Y: " << out.y
       << " Z: " << out.z
       << " RGB: " << out.rgb
       ;

    return os;
}

int main()
{
    std::ifstream points_file("points.txt");
    std::vector<point> points;
    std::copy(std::istream_iterator<point_line>(points_file),
              std::istream_iterator<point_line>(),
              std::back_inserter(points));

    std::copy(points.begin(),
              points.end(),
              std::ostream_iterator<point>(std::cout, "\n"));
}

【讨论】:

  • 这是我第一次将切片视为一种有意且有用的效果。虽然我想知道 - 这是允许的吗?它会产生内存泄漏吗?我不确定。
  • 我认为这是我第一次以这种方式使用它 :-) 它确实有效,point_lines 会在它们被切成 vector 后被销毁,所以我认为没有内存泄漏。也许我应该问这个问题......
  • 虽然,再想一想,我不认为存在内存问题。它会简单地调用point 的复制构造函数并引用point_line,这完全没问题。
  • @BjörnPollex:是的,这是我的想法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-11-19
  • 2010-09-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-14
相关资源
最近更新 更多