ChaoS Adm
ChaoS Adm

Reputation: 899

Why can I read int values from file in C++ but not float?

#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];
    }

The integer output is working as expected. But the double values are not? Also, the double values start right after the integer values, so I didn't move the file pointer to some other location.

Upvotes: 1

Views: 245

Answers (2)

Varun Nayak
Varun Nayak

Reputation: 310

Read values as a stringand then parse it as a float or an int.

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

If you expect the exponent format of float for e.g. 1e10 to be included, you may want to handle that case as well: (s.find('.') != string::npos) || (s.find('e') != string::npos).

Upvotes: 1

NathanOliver
NathanOliver

Reputation: 180935

When you do

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

}

The loop is going to run until the result of infile >> x is false. The result of infile >> x is the state of infile. If infile is good() then it is true, otherwise false. Once that loop gets to a point where infile is no longer good() it stops. Since you haven't done anything to change the state of infile after that, when you get to

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

}

infile is still bad, so it's false and the loop is skipped.

To reset the state of infile you need to call clear to reset the error state. That would give you

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

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

}

This will still have issues though since while(infile >> x) is not going to fail until it reaches the first . in your double values. That means the first double value you read in, and the last integer value will both be incorrect. One way to fix this is to read in the file using a std::string, and then parse the string to figure out if it an integer or floating point value and convert accordingly. Another option is to split up the data and have the integers in one file and the doubles in another.

Upvotes: 8

Related Questions