I need to read data from a file and send it to a vector to perform some calculations with them. The data looks like this:
- 0 524 36 12 8 7 96 0 2
- 1 11 22 55 77 88 88 96 15
- 78 45 65 32 78 98 65 54 12
I managed to put the data in a "istringstream", it change with each iteration as it should, but I cannot put the data in the vector, it keeps adding just the first line of the file (e.g 0 524 36 12 8 7 96 0 2).
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <vector>
int main() {
std::ifstream input;
std::string strInput;
std::istringstream strData;
std::vector<int> vectData;
input.open("input.txt");
for (int idx = 0; idx < 3; idx )
{
std::getline(input >> std::ws, strInput, '\n');
strData.str(strInput);
int idy;
//int index = 0;
while(strData >> idy)
{
vectData.push_back(idy);
// index;
}
std::cout << strData.str() << std::endl;
for (auto i:vectData)
{
std::cout<< i << ' ';
}
std::cout << '\n' << std::endl;
}
return 0;
}
I hope I have improved the question this time, thanks for all the suggestions.
CodePudding user response:
it keeps adding just the first line of the file
That's because it is the only one it has. You seem to be of the impression that the str
setter of std::istringstream
resets the stream state from its prior error/eof condition. It doesn't. Since you're reusing the same strData
member on each for-loop iteration, only the first one pushes through and fills the vector. After that the stream is in fail-state (by design, since that is what broke the inner-while-loop). When processing the next line, the stream is still in fail-state, and the while loop is effectively skipped.
Your options are numerous. For this trivial example I'd probably just do this, the most minimal change I can muster (which also fixes resetting the vector).
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <vector>
int main()
{
std::ifstream input;
std::string strInput;
input.open("input.txt");
for (int idx = 0; idx < 3; idx )
{
std::getline(input >> std::ws, strInput, '\n');
std::istringstream strData(strInput); // moved here
std::vector<int> vectData; // also moved here
int idy;
while (strData >> idy)
{
vectData.push_back(idy);
}
std::cout << strData.str() << std::endl;
for (auto i : vectData)
{
std::cout << i << ' ';
}
std::cout << '\n'
<< std::endl;
}
return 0;
}
Another considerably more concise and arguably more robust possibility is just this:
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <iterator>
int main()
{
std::ifstream input("input.txt");
if (input.is_open())
{
std::string strInput;
while (std::getline(input, strInput))
{
std::cout << strInput << '\n';
std::istringstream strData(strInput);
std::vector<int> vectData {
std::istream_iterator<int>(strData),
std::istream_iterator<int>()
};
for (auto i : vectData)
{
std::cout << i << ' ';
}
std::cout << "\n\n";
}
}
}
Output (for the given sample input)
0 524 36 12 8 7 96 0 2
0 524 36 12 8 7 96 0 2
1 11 22 55 77 88 88 96 15
1 11 22 55 77 88 88 96 15
78 45 65 32 78 98 65 54 12
78 45 65 32 78 98 65 54 12