0

If I have a text file that looks like:

4

1 2 3

4 5 6

7 8 9

10 11 12

I want to read each column of numbers into a variable x, y, and z. So after reading, z = [3, 6, 9, 12].

How do I parse through the text file to store every row of each column in its own variable?

So maybe store the entire text file as string with "/n" for each line, then parse x=sting[i], y=string[i+1], z=string[i+2] for each line? or something similar to that.

I think there must be a better way to do this, especially for when n is very big.

~ (edit) The first number at the top (4 in this case) determines how many rows the text file will have. So if I set n=4, then have a for loop: for(i=0; i

zmny
  • 119
  • 2
  • 2
  • 8
  • ~ (edit) The first number at the top (4 in this case) determines how many rows the text file will have. So if I set n=4, then have a for loop: for(i=0; i – zmny Sep 04 '12 at 21:33
  • That looks suspiciously like a homework format. Is this a real-world problem or an educational problem? If the latter, please add homework tag. – Robᵩ Sep 04 '12 at 21:33

3 Answers3

3

Read it one item at a time, adding each item to the appropriate array:

std::vector<int> x,y,z;
int xx, yy, zz;
while(std::cin >> xx >> yy >> zz) {
  x.push_back(xx);
  y.push_back(yy);
  z.push_back(zz);
}


EDIT: responding to added requirement
int n;
if( !( std::cin >> n) )
  return;

std::vector<int> x,y,z;
int xx, yy, zz;
while(n-- && std::cin >> xx >> yy >> zz) {
  x.push_back(xx);
  y.push_back(yy);
  z.push_back(zz);
}
Robᵩ
  • 143,876
  • 16
  • 205
  • 276
1

Going for "universal" solution (where n is the number of columns). In such case, instead of separate vector variables, it's better to go with vector of vectors:

std::fstream file("file.txt", ios_base::in);
std::vector< std::vector<int> > vars(n, vector<int>(100));
int curret_line = 0;

while (!file.eof())
{
  for (int i=0; i<n; ++i)
  {
    file >> vars[i][current_line];
  }
  ++current_line;
  // if current_line > vars[i].size() you should .resize() the vector
}

EDIT: updated loop according to comments below

int i=0, current_line = 0;
while (file >> vars[i][current_line])
{
  if (i++ == n) 
  {
    i = 0;
    ++current_line;
  }
}
Alex1985
  • 638
  • 3
  • 7
  • 2
    Please don't recommend using `.eof()` as a loop condition. It almost always produces buggy code, as it does in your example. See, for example, http://stackoverflow.com/questions/21647/reading-from-text-file-until-eof-repeats-last-line – Robᵩ Sep 04 '12 at 21:30
  • Or this: http://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong – jrok Sep 04 '12 at 21:31
0

Here's one way to do it, with some basic error checking. We'll treat a line with less than or more than 3 integers as an error:

#include <fstream>
#include <string>
#include <sstream>
#include <cctype>    

std::ifstream file("file.txt");
std::string line;
std::vector<int> x,y,z;

while (std::getline(file, line)) {
    int a, b, c;
    std::istringstream ss(line);

    // read three ints from the stream and see if it succeeds
    if (!(ss >> a >> b >> c)) {
        // error non-int or not enough ints on the line
        break;
    }

    // we read three ints, now we ignore any trailing whitespace
    // characters and see if we reached the end of line
    while (isspace(ss.peek()) ss.ignore();
    if (ss.get() != EOF) {
        // error, there are more characters on the line
        break;
    }

    // everything's fine
    x.push_back(a);
    y.push_back(b);
    z.push_back(c);
}
jrok
  • 51,107
  • 8
  • 99
  • 136
  • So how do I then print the arrays / vectors x,y,z? When I try "cout << x << endl;" i get an error that "< – zmny Sep 05 '12 at 01:30
  • Vector is a dynamicly resizeable array, you need to use operator [ ] to access individual elements. To print all, loop from 0 to x.size()-1 and print one by one. – jrok Sep 05 '12 at 06:42