在c ++错误中读取空格分隔值文件

时间:2013-08-08 08:44:21

标签: c++ file-io

我正在尝试从文件中获取浮点值以在我的程序中使用它们。我使用以下论坛来构建程序Read file line by line 但通过这样做获得的值似乎在最后被截断。

我的代码

#include <iostream>
#include <cstring>
#include <sstream>
#include <fstream>
using namespace std;

int main()
{

ifstream file;
file.open("test_file.ssv");
string line;
while(file.good() && (getline(file, line)))
{
    istringstream iss(line);
    double a, b, c;
    iss >> a >> b >>c ;
    cout << a <<endl;
}
file.close();
return (0);
}

我获得的输出是

9292.31
32432.2

虽然我的文件包含以下数据

9292.3123 4234.66 342.25423
32432.2423 3423.656 341.67841

有任何改进建议吗?

4 个答案:

答案 0 :(得分:2)

您的标准流可能具有较低的浮点精度,因此在使用float输出std::cout时只能看到一些小数。使用std::ios_base::precision来提高精度,并考虑使用std:: ios::floatfield输出固定或科学精度,例如:

// modify precision
#include <iostream>     // std::cout, std::ios

    int main () {
      double f = 3.14159;
      std::cout.unsetf ( std::ios::floatfield );                // floatfield not set
      std::cout.precision(5);
      std::cout << f << '\n';
      std::cout.precision(10);
      std::cout << f << '\n';
      std::cout.setf( std::ios::fixed, std:: ios::floatfield ); // floatfield set to fixed
      std::cout << f << '\n';
      return 0;
    }

输出:

  

3.1416   3.14159   3.1415900000

答案 1 :(得分:0)

这是cout精度的问题。 尝试测试比较:

cout << "Stand.: " << a << "  Prec.: " << fixed << setprecision(10) << a << endl;

答案 2 :(得分:0)

使用下面的代码会有所改进。

std::cout << std::setprecision(10) << a << std::endl;

有关详细信息,请参阅以下两个链接:
http://www.cplusplus.com/reference/ios/ios_base/precision/
http://www.cplusplus.com/reference/iomanip/setprecision/

用C ++编写快乐代码。 ; - )

答案 3 :(得分:0)

没有任何内容被截断。你不能截断double;它 始终具有相同的位数和相同的格式。但 你正在使用默认精度(6)和输出 默认格式,始终输出6位有效数字, 而且没有了。

这里有两个问题。第一个很简单:什么格式和 精确度你想要吗?有三种可能的格式: 默认(使用固定或科学,取决于 值,精度表示最大值 有效位数),固定或科学(其中 precision表示小数点后的位数。 因此,精度为6,取决于格式,您的第一个 价值将是:

default:    9292.31
fixed:      9292.312300
scientific: 9.292312E03

对于您显示的值,修复似乎最合适;但 如果你的值很小,它将显示较少的数字,和 对于非常大的值,您可以获得一些非常长的字符串。

通常的处理方法是为其定义一个操纵器 无论价值代表什么;在这种情况下,我只是称之为 values,因为我对你的事情一无所知 应用程序,但你应该找到一个更有意义的 名:

class value
{
    mutable std::ostream* myOwner;
    mutable std::ios_base::fmtflags myFlags;
    mutable int myPrecision;
    void capture( std::ostream& owner )
    {
        if ( myOwner == NULL ) {
            myOwner = &owner;
            myFlags = myOwner->fmtflags();
            myPrecision= myOwner->precision();
        }
    }
public:
    value() : myOwner( NULL ) {}
    ~value()
    {
        if ( myOwner != NULL ) {
            myOwner->flags( myFlags );
            myOwner->precision( myPrecision );
        }
    }
    friend std::ostream& operator<<( std::ostream& dest, value const& manip )
    {
        manip.capture( dest );
        dest.setf( std::ios_base::fixed, std::ios_base::floatfield );
        dest.precision( 6 );
    }
};

这也将恢复结尾处的格式化状态 完整表达(因为它应该只用作临时表达式); 这通常是一个好主意,因为它可以防止意外 以后的代码。如果你正在做任何重要的输出,你会 为保存和恢复创建一个基类,并派生你的 从那个实际操纵者。

一旦你有了这个,你可以写:

std::cout << value() << a << " " << b << " " << c << std::endl;

语句中value()之后的所有值都是 输出所需的格式。

更一般地说,你了解机器的浮点数吗? 作品?存储在您的双打中的实际值将 你在文件中看到的那些,因为你看到的那些 该文件不能以通常的双重格式表示。对于 输入的位数,你不应该看到任何数字 输出相同数字的数字,甚至是一个数字的差异 或者两个,但是如果输出非常多的数字 (约17)你可以。