【问题标题】:Why can I read int values from file in C++ but not float?为什么我可以在 C++ 中从文件中读取 int 值但不能浮动?
【发布时间】:2020-06-04 19:46:59
【问题描述】:
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;

int main()
{
    //Create a dynamic array to hold the values
    vector<int> integers;
    //Create a dynamic array to hold the values
    vector<double> floating;
    int x;
    double d;
    int sum1=0;
    double sum2=0.0;
    string line;
    ifstream infile;
    infile.open("data.txt", ios::in);

    while(infile >> x)
    {
        integers.push_back(x);

    }
    while(infile >> d)
    {
        floating.push_back(d);

    }
    int index = 0;
    infile.close();

    for(int i=0; i<integers.size(); i++)
    {
        sum1 += integers[i];
    }
    for(int i=0; i<floating.size(); i++)
    {
        sum2 += floating[i];
    }

整数输出按预期工作。但是双重价值不是吗?此外,双精度值在整数值之后开始,所以我没有将文件指针移动到其他位置。

【问题讨论】:

  • data.txt 长什么样子?预期的结果是什么?
  • 这是文本文件中的简单数据:“2 7 -6 -13 78 34 -1 2.5 5.6 -8.13”

标签: c++ file-handling


【解决方案1】:

当你这样做时

while(infile >> x)
{
    integers.push_back(x);

}

循环将一直运行,直到infile &gt;&gt; x 的结果为假。 infile &gt;&gt; x 的结果是infile 的状态。如果infilegood() 则为真,否则为假。一旦该循环到达infile 不再是good() 的地步,它就会停止。由于在那之后你没有做任何事情来改变infile的状态,当你到达时

while(infile >> d)
{
    floating.push_back(d);

}

infile 仍然很糟糕,所以它是false 并跳过了循环。

要重置infile 的状态,您需要调用clear 来重置错误状态。那会给你

while(infile >> x)
{
    integers.push_back(x);

}
infile.clear();
while(infile >> d)
{
    floating.push_back(d);

}

这仍然会有问题,因为 while(infile &gt;&gt; x) 在达到双精度值中的第一个 . 之前不会失败。这意味着您读入的第一个双精度值和最后一个整数值都将不正确。解决此问题的一种方法是使用std::string 读取文件,然后解析字符串以确定它是整数还是浮点值并进行相应的转换。另一种选择是拆分数据并将整数放在一个文件中,将双精度放在另一个文件中。

【讨论】:

  • 文件里面的数据是:“2 7 -6 -13 78 34 -1 2.5 5.6 -8.13”调用infile.clear()后,2.5读为0.5。
  • @ChaoSAdm 我刚刚添加到答案中以解释为什么会发生这种情况并为您提供了一些潜在的修复方法
  • @ChaoSAdm 这是因为当operator&gt;&gt; 读入int 时,它会将2.5 作为整数2 读取,并将.5 留在流中以供下次读取。 5.6-8.13 也可能发生同样的事情。 operator&gt;&gt; 在遇到不属于正在读入的类型的字符时停止读取。 . 字符不适用于int,因此operator&gt;&gt; 停止读取。
【解决方案2】:

将值读取为string,然后将其解析为floatint

    string s;
    while(infile >> s)
    {
        if (s.find('.') != string::npos) { // float
            floating.push_back(stof(s));
        } else {
            integers.push_back(stoi(s));
        }
    }

如果您期望 float 的指数格式,例如1e10 被包括在内,您可能也想处理这种情况:(s.find('.') != string::npos) || (s.find('e') != string::npos)

【讨论】:

  • 请注意,浮点数中不需要.。例如,1e10 是一个有效的浮点数。
  • 好点。如果他们希望包含指数格式,他们可以设置该条件:)
  • 您也可以先将字符串解析为int,如果失败则将其解析为float。无需事先手动检查格式
猜你喜欢
  • 1970-01-01
  • 2012-01-07
  • 1970-01-01
  • 1970-01-01
  • 2020-12-14
  • 2020-05-31
  • 2012-11-03
  • 2012-07-18
  • 1970-01-01
相关资源
最近更新 更多