Getting Started
  • Read the lab writeup: https://profmarz.com/index.php/cs102/labs/labH
  • There is no Debug for Lab H. Most of your time will go into the actual assignment.
  • This is the first lab where you must enable C++11. If you do not, you will end up having to use the "c_str()" function. Since this class runs on modern standards, we will enforce C++11 usage.

If you missed lab or failed to copy my code from the projector during lab session, the files I typed/utilised during lab sections 1 and 2 are available here: [LINK]
Synopsis
Welcome to your introduction to the most basic of data structures! You endured a few labs where you had to actually write your own classes. In this lab, you are given your class declarations (thankfully). Maybe it is because you don't know what a vector really is. We'll get more into that one later.

Your goal is to use the fstream library to read files into the vector class and matrix class given to you in class, and then do a multiplication with it. Afterwards, you will output the results into a file.
What is fstream?
fstream is another library you can include at the top of your program which will allow you to open, read, and write files. You will be introduced to two new data types known as ifstream and ofstream, which allow for opening a file for reading, and opening a file for writing respectively. The best way to tell is by an example(s).

Reading in from a file

Let's say we have a file called "test.txt":
This is a test
And let's say we have the following C++ program:
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int main() {
	string str1, str2;
	ifstream fp;         //Initialise ifstream class
	fp.open("test.txt"); //Tell it to open "test.txt" for reading
	fp >> str1 >> str2;  //Read first two words into "str1" and "str2"
	fp.close();          //Close the file
	cout << str1 << endl;
	cout << str2 << endl;
}
Simple enough, the file will be opened into the program and the first word will be read. This will be the output:
This
is
To put it simply: To the fstream library, a word is defined as a constant sequence of characters until broken by a space, or newline. It started at the beginning of the file, and read until there was a space. That is when it decided to stop reading in.

Writing to a file

Let's write a program that loops from 0 to 99, and prints it to the console. It is just a simple for loop, no?
#include <iostream>

using namespace std;

int main() {
	for (int i = 0; i < 100; i++) {
		cout << i << endl;
	}
}
If you don't know what this does, please do previous labs first. This loop prints out values from 0 to 99, as planned. What could we do to write them to a file? This is where the ofstream comes in:
#include <iostream>
#include <fstream>

using namespace std;

int main() {
	ofstream op;
	op.open("output.txt");              //Opens file for writing
	for (int i = 0; i < 100; i++) {
		op << i << endl;                //Writes each number to each line
	}
	op.close();                         //Closes the file
}
This code will produce a file called "output.txt" which has 100 lines counting from 0 to 99.

Similarities with cin and cout

If you noticed, ifstream acts exactly like how cin works with your input. It shouldn't surprise you then, that ofstream works the same as cout, except it is targeting a file. Because of this, you are more than welcome to utilise iomanip on ofstreams and they will work as planned. Hint: You will do that in this lab.
Error checking
We are computer scientists. We can not assume that every single file thrown into our program will work perfectly. This is why you must error check. What if you typed in a filename that doesn't exist? The program crashes. We want our program to handle that. This is also a very good habit to get into.

Checking if the file was opened properly

int main() {
	ifstream fp;
	fp.open("test.txt");
	if (fp.fail()) {
		cout << "Unable to open file." << endl;
		return 0;
	}
	//...
}
The same applies to ofstreams. I do not need to give an example for that. However, what about if we want to read a value from a file but it reached its end?

Checking if the value was read properly from a file

int main() {
	ifstream fp;
	string str;
	fp.open("test.txt");
	//.. fp.fail() checking ..//
	if (!(fp >> str)) {
		cout << "Unable to read from file." << endl;
	}
}
It looks nasty, but it does work. The reason why is because "fp >> str" actually returns a value when done reading in to str. The value it returns will tell you if "str" was properly set or not. If not, we are done reading the file or some other unknown error occured. And if you think you are smart by using fp.eof() instead, don't even try it.
The lab
We learned about fstreams for a reason. The reason is because this lab requires you to read from two files. The first one is a file that contains 4 numbers. That will be placed in your "vector" class. The second file contains 16 numbers. These will be placed in your "matrix" class.
The lab writeup doesn't give files, so I will supply my own:

vector1.txt
1 2 3 4

matrix1.txt
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16

I wrote a file in Lab Section 1 which demonstrated a very basic method for matrix multiplication if you didn't know how to do it. Here it is:
VECTOR:  1  2  3  4

MATRIX:  1  2  3  4
         5  6  7  8
         9 10 11 12
        13 14 15 16

//MULTIPLY EACH ROW BY VECTOR ELEMENTS
      (  1 * 1 ) + (  2 * 2 ) + (  3 * 3 ) + (  4 * 4 ) =  30
      (  5 * 1 ) + (  6 * 2 ) + (  7 * 3 ) + (  8 * 4 ) =  70
      (  9 * 1 ) + ( 10 * 2 ) + ( 11 * 3 ) + ( 12 * 4 ) = 110
      ( 13 * 1 ) + ( 14 * 2 ) + ( 15 * 3 ) + ( 16 * 4 ) = 150

//WRITE TO FILE
        30.0   70.0   110.0  150.0 
The lab is mainly split up into three parts: Reading in the vector and matrix, doing the multiplication, and then outputting to a file.

Reading in the vector

If you were paying attention above, I indirectly gave out half of the lab's code, because half of it is literally just reading in the files. Reading into the vector is simple. Make sure you have a global constant called "VECTOR_SIZE", and make sure it is set to 4. Then read in those values. Please do not hard-code this. Use a loop.

Reading into the matrix

This is where things get to be a little interesting. Notice that the matrix class has a 2D Array. Up until now, you have only worked with 1D Arrays. To sum it up, you simply add another [] to the array and you can access a new dimension. C++ allows you to do this to as many dimensions as you want (I've worked with 5D arrays before, just for reference).

A good way to read into a 2D Array is a nested for loop. Something like this:
for (int a = 0; a <VALUE_A; a++) {
	for (int b = 0; b <VALUE_B; b++) {
		//Do something with array[a][b]
	}
}
Since this lab forces your MATRIX_ROWS and MATRIX_COLS to be 4, this nested for loop will run 16 times, hence 16 values in matrix1.txt. Again, please do not hard-code 4 into your program. Use your constants.

Doing the multiplication

It is another nested for loop (Actually in Section 2, I showed an alternate way which had two nested for loops). Figure it out from there on.

Outputting to the file

If you read above in my "What is fstream?" section, you will notice I gave you all of the code you need to write the value of the end vector to a file. I even told you how to use your iomanip manipulators. You're welcome. :)