The code mixes formatted input (i.e. using the >>
operator for input) with unformatted input (in this case using std::getline()
). Unformatted input does not skip leading whitespace while formatted input does skip leading whitespace. In both cases reading stops as soon as the input is the next character wouldn't fit the format.
For example, reading a double
when the input is 3000.00\n...
stops after reading the last 0
because the '\n
doesn't fit the double
s format. The next character in the stream is, thus, a \n
. The function std::getline()
reads until it finds the first \n
which is immediately: it extracts that one character and [successfully] produces an empty line. With your input the sequence Dantooine
is next but doesn't fit the format of a double
and the stream goes into fail state.
The simple fix is to always skip leading white space when switching from formatted input to unformatted input, e.g., using the std::ws
manipulator:
std::getline(std::cin >> std::ws, s);
Whether this is suitable depends a bit on what you are trying to read. If the strings you want to read can start with a whitespace, you would need to be a bit more careful and, e.g., only extract whitespace up to the next newline:
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
(just ignoring one character may not work, e.g., if the input of the line ends in 3000.00 \n
).
Reading 3000.00
as long
actually stops at the .
, i.e., the first change to your program is to correct the type of values read to be double
rather than long
. Note that you should also always check that your input was successful before processing it. That is, I would actually use something like this:
double x0, y0, z0, x1, y1, z1;
std::string l0, l1;
while (0 < n--
&& std::getline(std::cin >> std::ws, l0)
&& std::cin >> x0 >> y0 >> z0
&& std::getline(std::cin >> std::ws, l1)
&& std::cin >> x1 >> y1 >> z1) {
// do something with the input
}