3

I have a file with this format:

-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

I read it with this code:

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();

Reading the scientific notation float results in a type mismatch.

How can I read all the numbers including the scientific notation float?

mskfisher
  • 3,291
  • 4
  • 35
  • 48
Luis
  • 678
  • 8
  • 14
  • 1
    did you try declaring the variables as double? – NirMH Jan 24 '12 at 12:05
  • I [cannot reproduce](http://ideone.com/Xl0ID) this error. Can you provide a complete program that shows the error (ideallly by modifying the example I posted)? – Björn Pollex Jan 24 '12 at 12:10
  • Tried declaring rgb as double, and is working. But I would love to be able to read the float directly... – Luis Jan 24 '12 at 12:27
  • You get a fail state if you try to read a float which is bigger that the max float (about 3.40E38). That isn't the case with the values you show here (they should be read as 0 in a float), but could explain why it works with double and not with float. – AProgrammer Jan 24 '12 at 12:51

2 Answers2

3

The problem is probably your while-loop. Never use while(inputFile.good()). Use this:

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

This answer to a different question explains why. You might also be interested in this answer, which suggests a more elegant solution.

Community
  • 1
  • 1
Björn Pollex
  • 75,346
  • 28
  • 201
  • 283
  • Posted the complete code, I will try your fix and see if it works. – Luis Jan 24 '12 at 12:22
  • 1
    @Luis: Seeing your code, I think you might want to approach this problem differently, as described in the second link in my answer. – Björn Pollex Jan 24 '12 at 12:27
  • @Luis: What exactly happens? Can you provide a complete example? Are you aware that your program will print `"Type mismatch during parsing."` even if everything ran fine? – Björn Pollex Jan 24 '12 at 12:30
  • Sorry corrected the else statement, if it reaches EOF it would not print any error message. Only if it doesn't get to EOF prints the error messages. – Luis Jan 24 '12 at 12:35
  • In your second link how would you discard what you don't need for the class like discard_1 and 2? – Luis Jan 24 '12 at 12:45
  • Good question. I am note sure. You could do it directly in the extraction-operator for `Point` by reading them into a dummy lie you did in your code (you only need one dummy-variable though). This is of course problematic if you want `Point` to work with different file-formats. In this case I think you could write a class `PointAdapter` that has an implicit cast to `Point` and an extraction-operator that can read the specific file-format. I will add a suggestion to my answer. – Björn Pollex Jan 24 '12 at 12:49
  • +1, looping structure is wrong, whenever there is another problem or not. – AProgrammer Jan 24 '12 at 12:52
  • @Luis: This is more complicated than I though, give me some time. – Björn Pollex Jan 24 '12 at 12:52
  • What happens exactly with the float rgb is that it stops reading the file after the z value, giving a type mismatch as if it did not recognise the scientific notation, with a normal float aka no scientific notation it works. Even changing the loop condition the only solution is declaring rgb as double... – Luis Jan 24 '12 at 12:58
0

Expanding upon Björn Pollex's answer with an example without any error-handling:

#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"));
}
Community
  • 1
  • 1
johnsyweb
  • 136,902
  • 23
  • 188
  • 247
  • 1
    This is the first time ever that I see slicing as an intentional and useful effect. Although I wonder - is this allowed? Could it produce a memory leak? I am unsure. – Björn Pollex Jan 24 '12 at 14:32
  • I think it's the first time that I've used it in this way :-) It certainly works and the `point_line`s would be destroyed after they'd been sliced into the `vector`, so I don't think there's a memory leak. Perhaps I should ask this as a question... – johnsyweb Jan 24 '12 at 14:35
  • Although, on second thought, I don't think there is a memory-problem. It will simply invoke the copy-constructor of `point` with a reference to `point_line`, which is totally fine. – Björn Pollex Jan 24 '12 at 14:35
  • @BjörnPollex: Yes, that was my thought. – johnsyweb Jan 24 '12 at 14:38