To be honest I don't think I understand most of it. |
Ok, here we go. I hope this isn't too basic.
A data stream is a sequence of bytes. These can come from memory, from disk, from a terminal, from a network interface and so on. In C++ it's common to treat file operations as streams to/from disk.
C++ provides a family of classes to deal with streams in the I/O Stream Library. The idea is you create the appropriate kind of stream, then read/write to them in a common way. The idea is a powerful one and starts with Multics, but that's another story.
So you use
stringstream
to deal with streams on memory,
fstream
to deal with streams on files, and there are a few predefined instances of streams that deal with terminals called
cin
,
cout
,
cerr
,
clog
.
So to read a number from a terminal you do:
And to read a number from a file:
1 2
|
std::iftream in("data.txt"); // create file stream instance
in >> number;
|
And to read a number that's in a string:
1 2 3
|
std::string str = "77"; // a string with a number
std::istringstream in(str); // create a string stream instance
in >> number;
|
Enough of that.
As you know, arrays hold sequences of things:
1 2
|
std::string string_array[10]; // an array of 10 strings
int number_array[5]; // an array of 5 ints
|
But what if you don't know how many elements you need before hand? That's what std::vector is. It's like an array, but it can grow. It's like arrays because you can use [] to get to each element, and it's like array because it knows what type it is storing. So vector equivalents of the declarations above are:
1 2
|
std::vector<std::string> string_vector(10); // a vector of strings with intial size 10
std::vector<int> int_vector(5); // vector of int with initial size 5
|
But you add to the end of a vector with
push_back
. For example:
|
int_vector.push_back(3); // add 3 to the end, int_vector now has size 6
|
I'll assume you know what
struct
is.
If you want to read three numbers from a stream that has
you can do so with:
1 2
|
int n[4];
std::cin >> n[0] >> n[1] >> n[2] >> n[3];
|
But what if you want to read:
You have to tell the stream that the comma character as well as the space and tab characters is white space. And that's what lines 7- 25, 36, and 38 do. But I won't explain them.
The rest should be straight forward.
line 37: create an input file instance
line 41: read a line from the input file stream to a string
lines 43-47: read the values from the string into a Row, a vector of ints.
line 49: add the row you just read to a vector of rows.
At the end you're left with a 2D grid of your data that you can access as:
1 2
|
rows[3][0]; // row 3, col 0
unsigned nrows = rows.size(); // I have this many rows
|