Home > Mobile >  Problems implementing vector as a data container C
Problems implementing vector as a data container C

Time:08-08

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 
  • Related