Your problem is in the condition of% internal while
. When you read the last number of a line, for example, your -1.23
, the flow stops just behind the -1.23
, without finding eof
, and therefore !ss.eof() == true
, entering the loop of new.
And with the empty line equal: if you have not yet started reading !ss.eof() == true
, and on entering, i == 1
.
Why is b
still worth 1.23
? Because when entering the loop even if there is no data, ss >> b
fails (here is when it finds eof
), and b
is not modified.
The solution is to replace the internal loop of:
while(!ss.eof())
for
while (ss >> b)
In saying, what interests you is to know if the reading ss >> b
could be completed. Anyway, you have more errors ( a
should be float
and there could be numbers less than -10000
), besides the fact that double
s are normally more efficient than float
s [†] .
Here the improved version:
#include <iostream>
#include <fstream>
#include <sstream>
#include <limits>
using namespace std;
int main()
{
ifstream f("mayores.txt");
string in;
while(getline(f, in)) { // Misma razón que con 'ss'.
int i = 0, j;
double a = std::numeric_limits<double>::min(), b;
istringstream ss(in);
while(ss >> b){
++i; // <pedantic_mode>: ++i es más eficiente que i++.
if(b > a){
a = b;
j = i;
}
}
if(i == 0) j = -1;
cout << j << endl;
}
}
Or, short version (although not more efficient), with iterators, that I love:
#include <iostream>
#include <fstream>
#include <sstream>
#include <limits>
#include <iterator>
#include <algorithm>
#include <vector>
#include <string>
using namespace std;
int main()
{
ifstream f("mayores.txt");
string in;
vector<double> line_values; // [†2]
while(getline(f, in)) {
line_values.clear();
istringstream ss(in);
copy(istream_iterator<double>(ss), istream_iterator<double>(),
back_inserter(line_values));
auto it = max_element(line_values.begin(), line_values.end());
cout << distance(line_values.begin(), it) - 1 << endl; // [†3]
}
}
[†]: Efficiency float
vs. double
depends on the architecture. If the floating point unit of the processor is implemented to deal with float
s, the double
s are slower because you have to transform the values returned by the processor ( float
) to the target type ( double
). And vice versa. As it turns out, most modern processors work natively with double
s.
[† 2]: Vectors reserve memory as they grow, and clear()
does not release previously reserved memory, so you do not have to rebook it. That is, the memory currently reserved by the vector ( capacity()
) is always greater than or equal to its current size ( size()
). That is why I declare the vector
out of the loop, to take advantage of the capacity()
acquired in previous laps of the loop.
[† 3]: max_element()
returns an iterator to the largest element. If the vector is empty, max_element(v.begin(), v.end()) == v.end()
, and std::distance
return 0.
NOTE: For the curious, here is a version with iterators that only goes through the sequence of values once:
#include <iostream>
#include <fstream>
#include <sstream>
#include <limits>
#include <iterator>
#include <algorithm>
#include <string>
using namespace std;
using double_reader = std::istream_iterator<double>;
int main()
{
istringstream f("mayores.txt");
string in;
while(getline(f, in)) {
istringstream ss(in);
int pos = -1, max_pos = -1;
double max = std::numeric_limits<double>::min();
for_each(double_reader(ss), double_reader(), [&](const double& d) {
++pos;
if (d > max) {
max = d;
max_pos = pos;
}
});
cout << max_pos << std::endl;
}
}