I finally got this exercise working and i just need someone to tell me im awesome.
Or just some feedback or tips on what i can improve(probably alot:)).

Write a program which performs addition, subtraction, multiplication of matrices. The dimensions of both the matrices would be specified by the user (dynamic memory allocation required). Use of structure or a class to define the matrix would be a good idea. (Expert)

main.cpp

#include "stdafx.h"
#include "MM.hpp"

using namespace std;
int main()
{
	Matrix i;

	i.read();
	cout << "Enter operator" << endl;
	char ch; cin >> ch; 
	while(ch != 'x' && ch != 'X' && ch != '*' && ch != '+' && ch != '-') { 
		cout << "invalid operator" << endl;
		cin >> ch; 
	}

	i.calculate(ch);
	i.print(ch);
	system("pause"); // cin.get() doesnt allways work :s
	return 0;
}

MM.hpp

#ifndef GUARD_MM_info
#define GUARD_MM_info

#include "stdafx.h"
#include <vector>
#include <string>
#include <iostream>
#include <utility>
#include <algorithm>

class Matrix {
public:
	typedef std::vector<std::vector<int> > matrix;
	int calculate(const char);
	void print(const char&);
	void read();
private:
	void Menu1(); void Menu2();
	void Menu3(); void Menu4();
	void Menu5(); void Menu6();
	int space(const int&);
	void readLeft();
	void readRight();
	void multiply();
	void add();
	void substract();
	std::pair<int, int> setSize(std::string);
	void setValues(const char&, matrix&, const std::pair<int, int>);
	matrix ML;
	matrix MR;
	matrix R;
	int spaces, spaceout;
};
void Matrix::multiply() {
	std::vector<int> v(MR[0].size(), 0);
	R = std::vector<std::vector<int> >(ML.size(), v);

	for(int i = 0; i != R.size(); i++)
		for(int j = 0; j != R[0].size(); j++) 
				
			if(ML.size() < MR[0].size())
				for(int k = 0; k != MR.size(); k++)
					R[i][j] += ( ML[i][k]*MR[k][i] );
			else 
				for(int k = 0; k != MR.size(); k++)
					R[i][j] += ( ML[i][k]*MR[k][j] );
	

}
void Matrix::add() {
	std::vector<int> v(std::max(ML[0].size(), MR[0].size()), 0);
	R = std::vector<std::vector<int> >(std::max(ML.size(), MR.size()), v);

	for(int i = 0; i != ML.size(); i++) 
		for(int j = 0; j != ML[0].size(); j++) 
			R[i][j]+=ML[i][j];

	for(int i = 0; i != MR.size(); i++) 
		for(int j = 0; j != MR[0].size(); j++) 
			R[i][j]+=MR[i][j];
}
void Matrix::substract() { 
	std::vector<int> v(std::max(ML[0].size(), MR[0].size()), 0);
	R = std::vector<std::vector<int> >(std::max(ML.size(), MR.size()), v);

	for(int i = 0; i != ML.size(); i++) 
		for(int j = 0; j != ML[0].size(); j++) 
			R[i][j]+=ML[i][j];

	for(int i = 0; i != MR.size(); i++) 
		for(int j = 0; j != MR[0].size(); j++) 
			R[i][j]-=MR[i][j];
}
int Matrix::calculate(const char c) {
	if (c == '*' || c == 'x' || c == 'X') {
		if(ML[0].size() == MR.size()) { multiply(); return 0; }
		else { Menu1(); Menu5(); Menu6();
		char ch; std::cin >> ch;
		while(ch != '1' && ch != '2') { Menu3(); std::cin >> ch; }
		if(ch == '1'){ readLeft(); calculate('*'); }
		else if(ch == '2'){ readRight(); calculate('*'); }
		}}
	if(c == '+') {
		if(ML.size() == MR.size() && ML[0].size() == MR[0].size()) { add(); return 0; }
		else { Menu2(); Menu5(); Menu6();
		char ch; std::cin >> ch; 
		while(ch != '1' && ch != '2') { Menu3(); std::cin >> ch; }
		if(ch == '1'){ readLeft(); calculate('+'); }
		else if(ch == '2'){ readRight(); calculate('+'); }
		}}
	if(c == '-') {
		if(ML.size() == MR.size() && ML[0].size() == MR[0].size()) { substract(); return 0; }
		else { Menu2(); Menu5(); Menu6();
		char ch; std::cin >> ch; 
		while(ch != '1' && ch != '2') { Menu3(); std::cin >> ch; }
		if(ch == '1'){ readLeft(); calculate('-'); }
		else if(ch == '2'){ readRight(); calculate('-'); }
		}}
	Menu3();
	char ch; std::cin >> ch; calculate(ch);
}
void Matrix::print(const char& c = ' ') {
	std::cout << std::endl;
	int sp1 = 3, sp2 = 3;
	for(std::vector<int>::size_type t = 0; t != std::max(ML.size(),MR.size()); t++) {

		if(ML.size() > t) {
			for(int j = 0; j != ML[0].size(); j++) {
				std::cout << "["<< std::string((3-space(ML[t][j])), ' ')
				<< ML[t][j] << "]";  if(t == 0)sp1+=5; }
			if(t == 0) std::cout << " " << c << " "; else std::cout << "   ";
		}else std::cout << std::string(sp1, ' ');

		if(MR.size() > t) {
			for(int j = 0; j != MR[0].size(); j++) {
				std::cout << "["<< std::string((3-space(MR[t][j])), ' ') 
				<< MR[t][j] << "]"; if(t == 0) sp2+=5; }
			if(t == 0) std::cout << " = "; else std::cout << "   ";
		}else std::cout << std::string(sp2, ' ');

		if(R.size() > t) {
			for(int j = 0; j != R[0].size(); j++)
				std::cout << "["<< std::string((3-space(R[t][j])), ' ')
				<< R[t][j] << "]";
		}
		std::cout << std::endl;
	}
}

void Matrix::Menu1() { std::cout << "Can not multiply, columns in left matrix  must equal rows in right matrix." << std::endl; }
void Matrix::Menu2() { std::cout << "Both matrixes have to be of the same size." << std::endl; }
void Matrix::Menu3() { std::cout << "You have not entered a valid operator(*, +, -), please try again." << std::endl; }
void Matrix::Menu4() { std::cout << "[3]Exit" << std::endl; }
void Matrix::Menu5() { std::cout << "[1]Change left matrix" << std::endl; }
void Matrix::Menu6() { std::cout << "[2]Change right matrix" << std::endl; }

int Matrix::space(const int& N) {
	if(N == 0) return 1;
	int n = N, s = 0;
	if(N<0){ n = N-(N*2); s++; }
	while(n>=1) {
		n = n/10;
		s++;
	}
	return s;
}

void Matrix::read() {
	std::pair<int, int> Left(setSize("Left"));
	std::pair<int, int> Right(setSize("Right"));
	setValues('L', ML, Left);
	setValues('R', MR, Right);
}
void Matrix::readRight() {
	std::pair<int, int> Right(setSize("Right"));
	setValues('R', MR, Right);
}
void Matrix::readLeft() {
	std::pair<int, int> Left(setSize("Left"));
	setValues('L', ML, Left);
}
std::pair<int, int> Matrix::setSize(std::string side) {
	std::string s = side;
	std::pair<int, int> p;
	std::cout << s << " matrix rows: "; std::cin >> p.first;
	std::cout << s << " matrix columns: "; std::cin >> p.second;
	return p;
}
void Matrix::setValues(const char& c, matrix& M, const std::pair<int, int> p) {
	// p.first = Rows;  p.second = Columns;
	int value = 0;

	std::vector<int> v(p.second, 0);
	M = std::vector<std::vector<int> >(p.first, v);
	
	for(int i = 0; i != p.first; i++) {
		for(int j = 0; j != p.second; j++) {
			std::cout << c <<"[" << i << "][" << j << "]:";
			std::cin >> value; M[i][j] = value; std::cout;
			spaces = std::max(1,space(M[i][j]));
		}	
	}
}
#endif

Awsome!

As a general rule, non-template code that is more complex than a single loop or a single if test should be compiled into its own object file (starting from its own cpp file), and the executable then depends on that object file as well as the one holding main(). (See: Linking in your compiler guide). In this case, MM.hpp would declare the Matrix class and stop after line 33. (and as a matter of sanity, it should be named either matrix.hpp or Matrix.hpp: You can name it anything, but you should make it easy to remember its name when you think about what it does.) From line 34 onward would be in a file named matrix.cpp, and it would also #include matrix.hpp What is the reason to have MR, ML etc as members of the Matrix class? This is very odd design. You want instead to have free (non-member) functions... might be static methods... that do the various operations on two matrices, and return the result. More like Matrix add(const Matrix& lhs, const Matrix& rhs); You also will want the Matrix class to have a constructor (or more than one) so that it is easy to create some matrices to do things with.

As a general rule, non-template code that is more complex than a single loop or a single if test should be compiled into its own object file (starting from its own cpp file), and the executable then depends on that object file as well as the one holding main(). (See: Linking in your compiler guide). In this case, MM.hpp would declare the Matrix class and stop after line 33. (and as a matter of sanity, it should be named either matrix.hpp or Matrix.hpp: You can name it anything, but you should make it easy to remember its name when you think about what it does.) From line 34 onward would be in a file named matrix.cpp, and it would also #include matrix.hpp

Thank you for feedback! I have just gotten used to putting it all in a .hpp because of the work i have done with template functions. When i have included anything regarding template in a .cpp its been a mess.

What is the reason to have MR, ML etc as members of the Matrix class? This is very odd design. You want instead to have free (non-member) functions... might be static methods... that do the various operations on two matrices, and return the result. More like
Matrix add(const Matrix& lhs, const Matrix& rhs);

Ah yes, thats right. What do would non-static methods be? I probably know but i cant connect to the right braincells. Edit: That doesnt return but works directly, i guess.

Edited 6 Years Ago by Andreas5: n/a

I have another question aswell, when i re-call

int Matrix::calculate(const char c) {

from within using calculate('*') etc, it does not recognize the character and skips right to the end. How come?

You said: Ah yes, thats right. What do would non-static methods be?
There are basically three kinds of functions:

  • global, free or namespace functions are not scoped by any class. Think printf
  • member functions are scoped by a class when declared, and always have an implicit this first parameter. You call them by saying something like fooInstance.memberFunction(arg, arg,...)
  • (class) static functions are scoped by a class when declared using the static keyword, and do not have an implicit "this" parameter. They are called by saying something like FooClass::staticFunction(arg, arg,...)

Any function may return an actual value, or may "return" void. You need to think about how is best to think about your Matrix class's methods such as add, subtract (PS: You misspelled "substract" in the class declaration), whatever.

  • If you want to say something like answer = aMatrix.subtract(bMatrix) then subtract is a member function. Even more if you want something like aMatrix.subtract(bMatrix); that just changes the value of aMatrix by the amount of bMatrix .
  • If you want to say answer = subtract(aMatrix, bMatrix); then you want a free or namespace function
  • If you want to say answer = Matrix::subtract(aMatrix,bMatrix); , then you want a static class function.

One of the powerful features of C++ is that you can declare overloaded operators, perhaps const Matrix& operator+(Matrix lhs, const Matrix& rhs) . Because you want to be able to do things like answer = aMatrix + bMatrix + cMatrix you need to declare that the return value is suitable as a parameter to be used by the next (leftward) operator in the chain. Based on the KISS principle, you want functions that "could be overloaded operators" to have a similar signature. Thus, if you end up choosing a class static function, you probably should declare it this:

/*class scope*/
  Matrix add(const Matrix& lhs, const Matrix& rhs);

Thank you for another very useful reply.
I will make a new project that would look something like this:

#include "matrice.hpp"
int main()
{
	using namespace matrix;
	using namespace std;

	matrice mleft, mright, mresult; // typedef for vec<vec<int> >
	
	read(mleft); read(mright);

	char ch;
	do { cout << "Enter operator: "; cin >> ch;
	if(ch == '*') mresult = mleft * mright; // etc
	} while ( ch != '*' ); // etc

	print(mleft, mright, mresult, ch);
}

I really need the practice anyway:)

Edited 6 Years Ago by Andreas5: n/a

I commented on your actual code. I comment it as I read it.

//Good, gaurds are good, but name them something useful like
// MATRIX_H_
#ifndef GUARD_MM_info
#define GUARD_MM_info

#include "stdafx.h"
#include <vector>
#include <string>
#include <iostream>
#include <utility>
#include <algorithm>

class Matrix {
public:
	//I like this typedef, although I would call it MatrixType.
	typedef std::vector<std::vector<int> > matrix;
	
	//there is really not point to make it const char, just use char
	//also what does calculate do? I cannot tell without looking at its implementation
	//so thats a bad sign already
	int calculate(const char);
	//forget about using reference in primitive types, they make no difference
	//plus a class should have minimal public methods it needs, so to make its job less
	//Thus you should'nt have print and read function in this class, it does not belong there
	void print(const char&);
	void read();
private:
	//Although Its private, at least give it better names so I can understand its job
	void Menu1(); void Menu2();
	void Menu3(); void Menu4();
	void Menu5(); void Menu6();
	//again const ref on primitive types is no point
	int space(const int&);
	void readLeft();
	void readRight();
	//add and subtract probably has very similar code, therefore you can abstract the problem
	//thus less code and easier time for you. 
	void multiply();
	void add();
	void substract();
	std::pair<int, int> setSize(std::string);
	void setValues(const char&, matrix&, const std::pair<int, int>);
	matrix ML;
	matrix MR;
	matrix R;
	int spaces, spaceout;
};
void Matrix::multiply() {
	std::vector<int> v(MR[0].size(), 0);
	R = std::vector<std::vector<int> >(ML.size(), v);

	for(int i = 0; i != R.size(); i++)
		for(int j = 0; j != R[0].size(); j++) 
				
			if(ML.size() < MR[0].size())
				for(int k = 0; k != MR.size(); k++)
					R[i][j] += ( ML[i][k]*MR[k][i] );
			else 
				for(int k = 0; k != MR.size(); k++)
					R[i][j] += ( ML[i][k]*MR[k][j] );
	

}
void Matrix::add() {
	std::vector<int> v(std::max(ML[0].size(), MR[0].size()), 0);
	R = std::vector<std::vector<int> >(std::max(ML.size(), MR.size()), v);

	for(int i = 0; i != ML.size(); i++) 
		for(int j = 0; j != ML[0].size(); j++) 
			R[i][j]+=ML[i][j];

	for(int i = 0; i != MR.size(); i++) 
		for(int j = 0; j != MR[0].size(); j++) 
			R[i][j]+=MR[i][j];
}
//you spelled subtract wrong ;)
void Matrix::substract() { 
	std::vector<int> v(std::max(ML[0].size(), MR[0].size()), 0);
	R = std::vector<std::vector<int> >(std::max(ML.size(), MR.size()), v);

	for(int i = 0; i != ML.size(); i++) 
		for(int j = 0; j != ML[0].size(); j++) 
			R[i][j]+=ML[i][j];

	for(int i = 0; i != MR.size(); i++) 
		for(int j = 0; j != MR[0].size(); j++) 
			R[i][j]-=MR[i][j];
}
//ouch, this is very bad.
int Matrix::calculate(const char c) {
	if (c == '*' || c == 'x' || c == 'X') {
		if(ML[0].size() == MR.size()) { multiply(); return 0; }
		else { Menu1(); Menu5(); Menu6();
		char ch; std::cin >> ch;
		while(ch != '1' && ch != '2') { Menu3(); std::cin >> ch; }
		if(ch == '1'){ readLeft(); calculate('*'); }
		else if(ch == '2'){ readRight(); calculate('*'); }
		}}
	if(c == '+') {
		if(ML.size() == MR.size() && ML[0].size() == MR[0].size()) { add(); return 0; }
		else { Menu2(); Menu5(); Menu6();
		char ch; std::cin >> ch; 
		while(ch != '1' && ch != '2') { Menu3(); std::cin >> ch; }
		if(ch == '1'){ readLeft(); calculate('+'); }
		else if(ch == '2'){ readRight(); calculate('+'); }
		}}
	if(c == '-') {
		if(ML.size() == MR.size() && ML[0].size() == MR[0].size()) { substract(); return 0; }
		else { Menu2(); Menu5(); Menu6();
		char ch; std::cin >> ch; 
		while(ch != '1' && ch != '2') { Menu3(); std::cin >> ch; }
		if(ch == '1'){ readLeft(); calculate('-'); }
		else if(ch == '2'){ readRight(); calculate('-'); }
		}}
	Menu3();
	char ch; std::cin >> ch; calculate(ch);
}

//again you should leave print to regular function, not member function
void Matrix::print(const char& c = ' ') {
	std::cout << std::endl;
	int sp1 = 3, sp2 = 3;
	for(std::vector<int>::size_type t = 0; t != std::max(ML.size(),MR.size()); t++) {

		if(ML.size() > t) {
			for(int j = 0; j != ML[0].size(); j++) {
				std::cout << "["<< std::string((3-space(ML[t][j])), ' ')
				<< ML[t][j] << "]";  if(t == 0)sp1+=5; }
			if(t == 0) std::cout << " " << c << " "; else std::cout << "   ";
		}else std::cout << std::string(sp1, ' ');

		if(MR.size() > t) {
			for(int j = 0; j != MR[0].size(); j++) {
				std::cout << "["<< std::string((3-space(MR[t][j])), ' ') 
				<< MR[t][j] << "]"; if(t == 0) sp2+=5; }
			if(t == 0) std::cout << " = "; else std::cout << "   ";
		}else std::cout << std::string(sp2, ' ');

		if(R.size() > t) {
			for(int j = 0; j != R[0].size(); j++)
				std::cout << "["<< std::string((3-space(R[t][j])), ' ')
				<< R[t][j] << "]";
		}
		std::cout << std::endl;
	}
}
//Oh I see now, this is not a menu, but rather error message, wow, very confusing
void Matrix::Menu1() { std::cout << "Can not multiply, columns in left matrix  must equal rows in right matrix." << std::endl; }
void Matrix::Menu2() { std::cout << "Both matrixes have to be of the same size." << std::endl; }
void Matrix::Menu3() { std::cout << "You have not entered a valid operator(*, +, -), please try again." << std::endl; }
void Matrix::Menu4() { std::cout << "[3]Exit" << std::endl; }
void Matrix::Menu5() { std::cout << "[1]Change left matrix" << std::endl; }
void Matrix::Menu6() { std::cout << "[2]Change right matrix" << std::endl; }

int Matrix::space(const int& N) {
	if(N == 0) return 1;
	int n = N, s = 0;
	if(N<0){ n = N-(N*2); s++; }
	while(n>=1) {
		n = n/10;
		s++;
	}
	return s;
}

void Matrix::read() {
	std::pair<int, int> Left(setSize("Left"));
	std::pair<int, int> Right(setSize("Right"));
	setValues('L', ML, Left);
	setValues('R', MR, Right);
}
void Matrix::readRight() {
	std::pair<int, int> Right(setSize("Right"));
	setValues('R', MR, Right);
}
void Matrix::readLeft() {
	std::pair<int, int> Left(setSize("Left"));
	setValues('L', ML, Left);
}
std::pair<int, int> Matrix::setSize(std::string side) {
	std::string s = side;
	std::pair<int, int> p;
	std::cout << s << " matrix rows: "; std::cin >> p.first;
	std::cout << s << " matrix columns: "; std::cin >> p.second;
	return p;
}
void Matrix::setValues(const char& c, matrix& M, const std::pair<int, int> p) {
	// p.first = Rows;  p.second = Columns;
	int value = 0;

	std::vector<int> v(p.second, 0);
	M = std::vector<std::vector<int> >(p.first, v);
	
	for(int i = 0; i != p.first; i++) {
		for(int j = 0; j != p.second; j++) {
			std::cout << c <<"[" << i << "][" << j << "]:";
			std::cin >> value; M[i][j] = value; std::cout;
			spaces = std::max(1,space(M[i][j]));
		}	
	}
}
#endif

Also you should make use of const-correct function.

As an example, here is a quick simple one I wrote. Compare it. I left out the multiplication operator because I didn't want to spend time on it.

#pragma once
#ifndef MATRIX_H_
#define MATRIX_H_


#include <vector>
#include <algorithm>
#include <functional>
#include <stdexcept>
#include <iostream>

struct DimensionException: std::exception{
	DimensionException() : exception(){}
	DimensionException(const char* msg) : exception( msg ){};
};

class Matrix{
public:
	typedef float DataType;
	typedef std::vector< std::vector<DataType> > MatrixType;
	typedef const Matrix constMatrix;
	typedef constMatrix& constMatrixRef;
	typedef MatrixType::size_type size_type;
private:
	size_type m_row;
	size_type m_col;
	MatrixType m_matrix;
public:
	//public interface
	Matrix(): m_row(0), m_col(0),m_matrix( m_row, std::vector< DataType >(m_col,0) )
	{		
	}
	Matrix(int row, int col, DataType initVal = 0)
		: m_row(row), m_col(col), m_matrix( m_row, std::vector< DataType >(m_col,initVal) )
	{
	}
	
	Matrix operator +(constMatrixRef mat)const{
		_validateSize(mat);
		return _performOp(mat,std::plus<DataType>());
	}
	Matrix operator -(constMatrixRef mat)const{
		_validateSize(mat);
		return _performOp(mat,std::minus<DataType>());
	}
	DataType& operator()(int row, int col){
		_validateIndex(row,col);
		return m_matrix[row][col];
	}
	const DataType& operator()(int row, int col)const{
		_validateIndex(row,col);
		return m_matrix[row][col];
	}
	size_type row()const{ return m_row; }
	size_type col()const{ return m_col; }
private:
	//helper functions
	void _validateSize(constMatrixRef mat)const{
		if( mat.m_row != m_row || mat.m_col != m_col)
			throw DimensionException("Invalid Dimension");
	}
	void _validateIndex(size_type r, size_type c)const{
		bool errFlag = false;
		if( r < 0 || r > m_row) errFlag = true;
		if( c < 0 || c > m_col) errFlag = true;
		if(errFlag) throw std::out_of_range("Index out of range");
	}
	template<typename BinaryOp>
	Matrix _performOp(constMatrixRef rhs, const BinaryOp& op)const{
		Matrix m( m_row, m_col );
		constMatrixRef lhs = *this;
		for(int r = 0; r != m_row; ++r){
			for(int c = 0; c != m_col; ++c){
				m(r,c) = op( lhs(r,c), rhs(r,c) );
			}
		}
		return m;
	}
};

//outside function
void printMatrix(Matrix::constMatrixRef m){
	for(int r = 0; r != m.row(); ++r){
		for(int c = 0; c != m.col(); ++c){
			std::cout << m(r,c) << " ";
		}
		std::cout << std::endl;
	}
	std::cout << std::endl;
}

#endif

//main.cpp
int main(){
	using namespace std;

	Matrix mat1(2,2,50);

	cout <<"Mat1 = \n";
	printMatrix(mat1);

	Matrix mat2(2,2,100);
	cout << "Mat2 = \n";
	printMatrix(mat2);

	cout << "Mat1 - mat2 = \n";
	printMatrix( mat1 - mat2 );
	
	cout << "Mat1 + mat2 = \n";
	printMatrix( mat1 + mat2 );
}

Thanks for taking the time to look into my project. I have alot to learn! I just finished my second attempt before i saw your reply, its cleaner and looks more sane, even tho it still probably has some weird twists:P Alot of code here already but i will post it anyway:

#include "stdafx.h"
#include "matrix.h"
#include <iostream>

using namespace std;
using namespace matrix;

int main()
{
	matrice i, j, r;
	read(i, 'L'); read(j, 'R');
	char c;
	do { cout << "Enter operator(*, +, -)" << endl; cin >> c; }
	while(!validoperation(i, j, c)); // break if operation is, or becomes valid

	if(c == '*') r = i * j;
	else if(c == '+') r = i + j;
	else if(c == '-') r = i - j;

	print(i, j, r, c);

	cin >> c;

	return 0;
}
#ifndef GUARD_matrix_info
#define GUARD_matrix_info

#include <vector>

namespace matrix {

	typedef std::vector<std::vector<int> > matrice;

	int space(const int&);
	void standardmenu();
	void read(matrice&, const char&);
	void print(const matrice&, const matrice&, const matrice&, const char&);
	int validoperation(matrice&, matrice&, char&);

	matrice subtract(const matrice&, const matrice&);
	matrice add(const matrice&, const matrice&);
	matrice multiply(const matrice&, const matrice&);

	inline matrice operator+(const matrice& l, const matrice& r) { return add(l, r); }
	inline matrice operator-(const matrice& l, const matrice& r) { return subtract(l, r); }
	inline matrice operator*(const matrice& l, const matrice& r) { return multiply(l, r); }
}
#endif
#include "stdafx.h"
#include <string>
#include <vector>
#include <iostream>
#include <utility>
#include <algorithm>
#include "matrix.h"

using std::string; using std::vector; using std::cin;
using std::cout; using std::endl; using std::max;

namespace matrix {

	void print(const matrice& ML, const matrice& MR, const matrice& R, const char& c = ' ') {
		std::cout << std::endl;
		int sp1 = 3, sp2 = 3;
		for(std::vector<int>::size_type t = 0; t != std::max(ML.size(),MR.size()); t++) {

			if(ML.size() > t) {
				for(int j = 0; j != ML[0].size(); j++) {
					std::cout << "["<< std::string((3-space(ML[t][j])), ' ')
					<< ML[t][j] << "]";  if(t == 0)sp1+=5; }
				if(t == 0) std::cout << " " << c << " "; else std::cout << "   ";
			}else std::cout << std::string(sp1, ' ');

			if(MR.size() > t) {
				for(int j = 0; j != MR[0].size(); j++) {
					std::cout << "["<< std::string((3-space(MR[t][j])), ' ') 
					<< MR[t][j] << "]"; if(t == 0) sp2+=5; }
				if(t == 0) std::cout << " = "; else std::cout << "   ";
			}else std::cout << std::string(sp2, ' ');

			if(R.size() > t) {
				for(int j = 0; j != R[0].size(); j++)
					std::cout << "["<< std::string((3-space(R[t][j])), ' ')
					<< R[t][j] << "]";
			}
			std::cout << std::endl;
		}
	}

	void standardmenu() {
		cout << "[1]Change left matrice" << endl
			 << "[2]Change right matrice" << endl
			 << "[3]Change operation" << endl;
	}

	int validoperation(matrice& ML, matrice& MR, char& c) {
		if (c == '*' || c == 'x' || c == 'X') {
			if(!(ML[0].size() == MR.size())) { 
				cout << "ERROR: Left columns must be of the"
				" same size as the right row to multiply." << endl;
				standardmenu();
				char menu;
				do { cin >> menu;
					if(menu == '1') read(ML, 'L');
					else if(menu == '2') read(MR, 'R');
					else if(menu == '3') return false; }
				while( menu != '1' && menu != '2' && menu != '3' );
			}}	
		if(c == '+') {
			if(!(ML.size() == MR.size() && ML[0].size() == MR[0].size())) { 
				cout << "ERROR: Both matrices have to be of the"
				" same size in order to perform addition" << endl;
				standardmenu();
				char menu;
				do { cin >> menu;
					if(menu == '1') read(ML, 'L');
					else if(menu == '2') read(MR, 'R');
					else if(menu == '3') return false; }
				while( menu != '1' && menu != '2' && menu != '3' );
		}}
		if(c == '-') {
			if(!(ML.size() == MR.size() && ML[0].size() == MR[0].size())) { 
				cout << "ERROR: Both matrices have to be of the"
				" same size in order to perform subtraction" << endl;
				standardmenu();
				char menu;
				do { cin >> menu;
					if(menu == '1') read(ML, 'L');
					else if(menu == '2') read(MR, 'R');
					else if(menu == '3') return false; }
				while( menu != '1' && menu != '2' && menu != '3' );
			}
		}return true;
	}

	int space(const int& N) {
		if(N == 0) return 1;
		int n = N, s = 0;
		if(N<0){ n = N-(N*2); s++; }
		while(n>=1) {
			n = n/10;
			s++;
		}
		return s;
	}
	void read(matrice& M, const char& c) {
		int value = 0, rows = 0, columns = 0;

		string s = "";
		if(c == 'L') s = "Left"; else if(c == 'R') s = "Right";
		cout << s << " matrix rows: "; cin >> rows;
		cout << s << " matrix columns: "; cin >> columns;

		std::vector<int> v(columns, 0);
		M = vector<vector<int> >(rows, v);
		
		for(int i = 0; i != rows; i++) {
			for(int j = 0; j != columns; j++) {
				cout << c <<"[" << i << "][" << j << "]:";
				cin >> value; M[i][j] = value;
	}}}
	// matrice calculations
	matrice subtract(const matrice& ML, const matrice& MR) { 
		vector<int> v(ML[0].size(), 0);
		matrice R = std::vector<std::vector<int> >(ML.size(), v);

		for(int i = 0; i != ML.size(); i++) 
			for(int j = 0; j != ML[0].size(); j++) 
				R[i][j]+=ML[i][j];

		for(int i = 0; i != MR.size(); i++) 
			for(int j = 0; j != MR[0].size(); j++) 
				R[i][j]-=MR[i][j];
		return R;
	}
	matrice add(const matrice& ML, const matrice& MR) {
		vector<int> v(ML[0].size(), 0);
		matrice R = vector<vector<int> >(ML.size(), v);

		for(int i = 0; i != ML.size(); i++) 
			for(int j = 0; j != ML[0].size(); j++) 
				R[i][j]+=ML[i][j];

		for(int i = 0; i != MR.size(); i++) 
			for(int j = 0; j != MR[0].size(); j++) 
				R[i][j]+=MR[i][j];
		return R;
	}
	matrice multiply(const matrice& ML, const matrice& MR) {
		vector<int> v(MR[0].size(), 0);
		matrice R = vector<vector<int> >(ML.size(), v);

		for(int i = 0; i != R.size(); i++)
			for(int j = 0; j != R[0].size(); j++) 
					
				if(ML.size() < MR[0].size())
					for(int k = 0; k != MR.size(); k++)
						R[i][j] += ( ML[i][k]*MR[k][i] );
				else 
					for(int k = 0; k != MR.size(); k++)
						R[i][j] += ( ML[i][k]*MR[k][j] );
		return R;
	}
}
This article has been dead for over six months. Start a new discussion instead.