Reputation: 139
I'm having an issue with istringstream not storing the values it reads. Here is what I have:
if(inputFile.good()){ //Make sure file is open before trying to work with it
//Begin Working with information
cout << "\tIn File: " << input << endl;
cout << "------------------------------------" << endl;
int number_of_lines = 0;
std::string line;
while (std::getline(inputFile, line)){
++number_of_lines;
}
Time times[number_of_lines];
double math[number_of_lines];
std::string input;
int hh, mm;
for(int loop=0;loop<number_of_lines;loop++){
std::getline(inputFile, input);
std::istringstream(input) >> mm >> hh >> math[loop];
cout << "hours = " << hh << endl;
times[loop].setTimeHours(hh);
times[loop].setTimeMinutes(mm);
times[loop].show();
cout << "*" << math[loop] << endl;
}
std::cout << "Number of lines in text file: " << number_of_lines << "\n" << endl;
}else{
cout << "Could not open file!!!" << endl;
}
The file I'm reading looks like this:
90 1 3.0
1 1 100.0
2 34 5.1
And the output when I run:
In File: data04.txt
------------------------------------
hours = 0
Operation To Be Done = 0:2336552*1.15384e-317
hours = 0
Operation To Be Done = 0:2336552*1.58101e-322
hours = 0
Operation To Be Done = 0:2336552*1.15397e-317
Number of lines in text file: 3
Anyone know why its not storing the values?
Upvotes: 0
Views: 158
Reputation: 19742
First and foremost, your program is wrong. After the while
loop ends, there is nothing more to read in the file (unless you seekg()
back to the beginning), so the std::getline()
call in the for
loop body basically does nothing.
A second problem is that concerns are not properly separated.
Here is how I would have implemented this program:
struct line_data
{
Time t;
double x;
};
// This handles reading a single Time value.
std::istream & operator >> (std::istream & is, Time & t)
{
int hh, mm;
if (is >> hh >> mm)
{
// Not happy with the following two lines, too Java-like. :-(
t.setTimeHours(hh);
t.setTimeMinutes(mm);
}
return is;
}
// This handles reading a single line of data.
std::istream & operator >> (std::istream & is, line_data & ld)
{
std::string s;
if (std::getline(is, s))
{
std::istringstream iss(s);
// Ensure errors are propagated from iss to is.
if (!(iss >> ld.t >> ld.x))
is.setstate(std::ios::failbit);
}
return is;
};
// This handles processing a single line of data.
struct line_manip // satisfies concept OutputIterator<line_data>
{
std::back_insert_iterator<std::vector<Time>> ti;
std::back_insert_iterator<std::vector<double>> xi;
line_manip(std::vector<Time> & ts, std::vector<double> & xs)
: ti(std::back_inserter(ts))
, xi(std::back_inserter(xs))
{
}
line_manip & operator = (const line_data & ld)
{
ti = ld.t;
xi = ld.x;
return *this;
}
line_manip & operator * () { return *this; }
line_manip & operator ++ () { return *this; }
line_manip & operator ++ (int) { return *this; }
};
int main()
{
std::ifstream ifs("input.txt");
std::vector<Time> ts;
std::vector<double> xs;
std::copy(std::istream_iterator<line_data>(ifs),
std::istream_iterator<line_data>(),
line_manip(ts, xs));
// ...
}
Upvotes: 0
Reputation: 153840
There are several key problems in this code
std::vector<Time>
(or similar container). Aside from only traversing the file once, on UNIXes the file size can change while reading.std::vector<Time>
instead.Upvotes: 2