0

I have an ASCII file (students.txt) that looks as follows (Ignore empty lines, they're an artifact of my unfamiliarity with this formatting tool):

stella 10 4.4 ...
peter 1.1 5 ...

That is, each line starts with a name, followed by one or more numbers.

The code snippet below is meant to read this file line by line, reading the name into a string and the numbers into a double, printing each of these in turn. When I run this on Ubuntu, it works fine and I get

stella 10 4.4
peter 1.1 5

However, when I run it on a Mac, I get the following:

stella 10 4.4
ter 1.1 5

When I change 'peter' to 'speter', however, it works fine...:

stella 10 4.4
speter 1.1 5

Any thoughts...?

#include <iostream>
#include <fstream>
#include <string>

using namespace std;


int main() {

  ifstream infile("students.txt");
  string name;
  double x;

  while ( !infile.eof() ) {
    infile >> name;
    cout << name << ' ';
    while ( infile >> x ){
      cout << x << ' ';
    }
    cout << endl;
    if (! infile.eof() )
      infile.clear();
  }

  return 0;
}
NathanOliver
  • 171,901
  • 28
  • 288
  • 402
Marco
  • 35
  • 1
  • 9
  • 2
    FYI [Why is “while ( !feof (file) )” always wrong?](http://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong) – NathanOliver Nov 02 '15 at 13:18

2 Answers2

0

When the input starts out divided into lines, it's usually easiest to read it by lines, then split those into the component pieces:

std::string line;

std::string name;
std::vector<double> values;

while (std::getline(infile, line)) {
    std::istringstream buffer(line);
    double temp;

    buffer >> name;
    while (buffer >> temp)
        values.push_back(temp);
}
Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • Thanks for your reply; However, I'd be particularly interested why my snippet produces a different result on linux and mac...:o) – Marco Nov 02 '15 at 14:43
  • @Marco: My first guess would be that the library you're using on the Mac simply has a bug. – Jerry Coffin Nov 02 '15 at 16:26
0

I'd be particularly interested why my snippet produces a different result on linux and mac...

I think this behavior is due to differences in how floating point inputs are handled in input streams in Libc++ vs. Libstdc++ (rather than Mac vs. Ubuntu)

You're most likely using Libc++ (LLVM/Clang's standard C++ library) on Mac since Apple deprecated Libstdc++ (the GNU standard C++ library that comes standard in Linux).

In this case, Libc++ will "eat" any characters that could potentially be converted into a double, while Libstdc++ will not (e.g. it "eats" the pe in peter because p and e could potentially be part of the representation of a double).

For example, if your students.txt looked like this:

0x1a 90.2 84.3
0x1a 1.5 56.4

When you compile your original program with Libstdc++ and run it, you get:

0x1a 90.2 84.3 0 
x1a 1.5 56.4

While compiling it with Libc++ and running gives:

0x1a 90.2 84.3 26 1.5 56.4

Libc++ recognizes 0x1a as a hex number (26), while Libstdc++ only converts the 0 in 0x1a and parses x1a into the string name.

For a much more detailed explanation including examples, see https://github.com/tardate/LittleCodingKata/blob/master/cpp/DoubleTrouble/README.md

cdwilson
  • 4,310
  • 4
  • 26
  • 32