Astmara
Astmara

Reputation: 11

read string and numbers to vector c++

What can I do when my file s2.txt looks like

ID 1 (string) 
22 30 30 4 2 4 5 7 5 3 ......................................(a few lines   
of numbers) 
ID 2
30 4 2 1 2 ................................. (other lines of numbers)

I want save numbers to vector but it doesn't work:

void readFromFile (){
      ifstream file("s2.txt");
      if( file.good() == true )
          cout << "open" << endl;
      else
          cout << "denied" << endl;

      int m=0;
      while(!file.eof()) {
        string ID;
        int qual;
        vector <int> quality;
        getline(file,ID);
        while (file>>qual) {
          quality.push_back(qual);
          cout<<quality[m]<<endl;
          m++;
        }
      }
      file.close();
    }
}

main () {
readFromFile();
}

When I click "Run" only one string of numbers is save to a vector (for ID1).

PS. Reading ID is not important.

Upvotes: 0

Views: 1419

Answers (2)

Scheff&#39;s Cat
Scheff&#39;s Cat

Reputation: 20141

As suggested in the answer of Linh Dao, I made a respective sample code:

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>

void readFromFile(std::istream &in)
{
  if (!in.good()) {
    std::cerr << "ERROR!" << std::endl;
  }
  std::string buffer;
  std::vector<int> quality;
  while (std::getline(in, buffer)) {
    if (buffer.size() >= 2 && buffer.compare(0, 2, "ID") == 0) {
      std::cout << buffer << std::endl;
      quality.clear(); // reset quality vector
    } else {
      // read numbers
      std::istringstream in(buffer); int qual;
      while (in >> qual) {
        quality.push_back(qual);
        std::cout << quality.back() << std::endl;
      }
    }
  }
}

int main(void)
{
#if 0 // in OP
  { std::ifstream fIn("s2.txt");
    readFromFile(fIn);
  } // fIn goes out of scope -> file is closed
#else // instead
  readFromFile(std::cin);
#endif // 0
  return 0;
}

Input:

ID 1 (string) 
22 30 30 4 2 4 5 7 5 3
22 30 30 4 2 4 5 7 5 3
ID 2
30 4 2 1 2

Output:

ID 1 (string) 
22
30
30
4
2
4
5
7
5
3
22
30
30
4
2
4
5
7
5
3
ID 2
30
4
2
1
2

Life demo on ideone.

Note:

The input stream is read line by line (into std::string buffer). The further processing depends on whether the input buffer contents starts with ID. If not, the buffer is used with std::istringstream to extract int numbers.


If I understood the comment right, the questioner intended to output the whole collected quality vector in each iteration. Hence, I modified the first sample and added an output operator<<() for std::vector<int>:

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>

// a stream operator for vector<int> ouput
std::ostream& operator<<(std::ostream &out, const std::vector<int> &values)
{
  const char *sep = "";
  for (int value : values) {
    out << sep << value; sep = " ";
  }
  return out;
}

void readFromFile(std::istream &in)
{
  if (!in.good()) {
    std::cerr << "ERROR!" << std::endl;
  }
  std::string buffer;
  std::vector<int> quality;
  while (std::getline(in, buffer)) {
    if (buffer.size() >= 2 && buffer.compare(0, 2, "ID") == 0) {
      std::cout << buffer << std::endl;
      quality.clear(); // reset quality vector
    } else {
      // read numbers
      std::istringstream in(buffer); int qual;
      while (in >> qual) {
        quality.push_back(qual);
        std::cout << quality << std::endl;
      }
    }
  }
}

int main(void)
{
#if 0 // in OP
  { std::ifstream fIn("s2.txt");
    readFromFile(fIn);
  } // fIn goes out of scope -> file is closed
#else // instead
  readFromFile(std::cin);
#endif // 0
  return 0;
}

Input: the same like above

Output:

ID 1 (string) 
22
22 30
22 30 30
22 30 30 4
22 30 30 4 2
22 30 30 4 2 4
22 30 30 4 2 4 5
22 30 30 4 2 4 5 7
22 30 30 4 2 4 5 7 5
22 30 30 4 2 4 5 7 5 3
22 30 30 4 2 4 5 7 5 3 22
22 30 30 4 2 4 5 7 5 3 22 30
22 30 30 4 2 4 5 7 5 3 22 30 30
22 30 30 4 2 4 5 7 5 3 22 30 30 4
22 30 30 4 2 4 5 7 5 3 22 30 30 4 2
22 30 30 4 2 4 5 7 5 3 22 30 30 4 2 4
22 30 30 4 2 4 5 7 5 3 22 30 30 4 2 4 5
22 30 30 4 2 4 5 7 5 3 22 30 30 4 2 4 5 7
22 30 30 4 2 4 5 7 5 3 22 30 30 4 2 4 5 7 5
22 30 30 4 2 4 5 7 5 3 22 30 30 4 2 4 5 7 5 3
ID 2
30
30 4
30 4 2
30 4 2 1
30 4 2 1 2

Life demo on ideone.

Upvotes: 1

Linh Dao
Linh Dao

Reputation: 1653

You should read each line to a string. Then check for "ID" string. If "ID" string is found at position 0 of a line then read that line as a ID line, if not, read that line as a line of integer numbers.

Upvotes: 3

Related Questions