My code for outputting boxes, outputs only spaces.
#include <iostream>
using namespace std;
class box{
int x, y;
public:
box(int i, int j){ x = i; y = j; }
friend ostream &operator<<(ostream &stream, box o);
};
ostream &operator<<(ostream &stream, box o)
{
register int i, j;
for (i = 0; i < o.x; i++)
stream << "*";
stream << "\n";
for (j = 1; j < o.y-1; j++){
for (i = 0; i < o.x; i++)
if (i == 0 || i == o.x - 1) stream << "*";
else stream << " ";
stream << "\n";
}
for (i = 0; i < o.x; i++)
stream << "*";
stream << "\n";
return stream;
}
int main(){
box a(14, 6), b(30, 7), c(40, 5);
cout << a << b << c;
return 0;
}
This is supposed to output some boxes made of *
but the only thing it does is create some newlines and spaces.
It doesn't even print box b or box c
EDIT : i found the mistake and corrected it , thanks to everyone
I think that instead of
box(int i, int j){ i = x; j = y; }
you mean
box( int i, int j ) : x( i ), y( j ) {}
And it is better to declare the operator like
friend ostream &operator<<(ostream &stream, const box &o);
Related
This project I am writing in order to create a Square Matrix ADT object has a problem with the constructor (not the default constructor). I have traced the problem back to the constructor but I cannot figure out what is wrong with it which makes it crash everytime I try to run my test in main.cpp.
I usually get an error that say something along the lines "Thread 1: EXC_BAD_ACCESS: ..." and the console usually says "(11db)"
Does anyone have any ideas on what might be causing all the problems?
This is the header file:
#include <iostream>
#include <vector>
using namespace std;
#ifndef SquareMatrix_h
#define SquareMatrix_h
class SquareMatrix {
private:
vector<vector<double>> numMatrix;
public:
SquareMatrix();
SquareMatrix(vector<vector<double>>& v2d);
double getValue(int x, int y);
void setValue(int x, int y, double value);
friend SquareMatrix operator * (SquareMatrix m1, SquareMatrix m2);
friend SquareMatrix operator - (SquareMatrix m1, SquareMatrix m2);
friend ostream& operator <<(ostream &out, SquareMatrix m);
};
#endif /* SquareMatrix_h */
This is my SquareMatrix.cpp file: (The constructor that I believe isn't working is the second function in the code: SquareMatrix::SquareMatrix(vector>& v2d) {...)
#include "SquareMatrix.h"
#include <iostream>
using namespace std;
SquareMatrix::SquareMatrix() {
numMatrix.clear();
for(int i = 0; i < 10; i++) {
vector<double> initial;
for(int j = 0; j < 10; j++) {
initial.push_back(0.0);
}
numMatrix.push_back(initial);
}
}
SquareMatrix::SquareMatrix(vector<vector<double>>& v2d) {
bool flagSize = true;
for(int i = 0; i < v2d.size(); i++) {
if(v2d[i].size() != v2d.size()) {
flagSize = false;
break;
}
}
if(flagSize) {
numMatrix.clear();
for(int i = 0; i < v2d.size(); i++) {
vector<double> initial;
for(int j = 0; j < v2d[i].size(); i++) {
initial.push_back(v2d[i][j]);
}
numMatrix.push_back(initial);
}
} else {
numMatrix.clear();
for(int i = 0; i < 10; i++) {
vector<double> initial;
for(int j = 0; j < 10; j++) {
initial.push_back(0.0);
}
numMatrix.push_back(initial);
}
}
}
double SquareMatrix::getValue(int x, int y) {
if((x < numMatrix.size()) && (y < numMatrix.size()) && (x >= 0) && (y >= 0)) {
return numMatrix[x][y];
}
return 0;
}
void SquareMatrix::setValue(int x, int y, double value) {
if((x < numMatrix.size()) && (y < numMatrix.size()) && (x >= 0) && (y >= 0)) {
numMatrix[x][y] = value;
}
}
SquareMatrix operator * (SquareMatrix m1, SquareMatrix m2) {
if(m1.numMatrix.size() == m2.numMatrix.size()) {
vector<vector<double>> result;
for(int i = 0; i < m1.numMatrix.size(); i++) {
vector<double> initial;
for(int j = 0; j < m1.numMatrix.size(); j++) {
initial.push_back(0);
}
result.push_back(initial);
}
for(int i = 0; i < m1.numMatrix.size(); i++) {
for(int j = 0; j < m1.numMatrix.size(); j++) {
result[i][j] = 0;
for (int a = 0; a < m1.numMatrix.size(); a++) {
result[i][j] += m1.numMatrix[i][a] + m2.numMatrix[a][j];
}
}
}
return SquareMatrix(result);
}
return SquareMatrix();
}
SquareMatrix operator - (SquareMatrix m1, SquareMatrix m2) {
if(m1.numMatrix.size() == m2.numMatrix.size()) {
vector<vector<double>> result;
for(int i = 0; i < m1.numMatrix.size(); i++) {
vector<double> initial;
for(int j = 0; j < m1.numMatrix[i].size(); j++) {
double pushNum = (m1.getValue(i,j) - m2.getValue(i,j));
initial.push_back(pushNum);
}
result.push_back(initial);
}
return SquareMatrix(result);
}
return SquareMatrix();
}
ostream& operator << (ostream &out, SquareMatrix m) {
out << "(";
for (int i = 0; i < m.numMatrix.size(); i++) {
for (int j = 0; j < m.numMatrix.size(); j++) {
out << " " << m.numMatrix[i][j];
if(j != (m.numMatrix.size() - 1)) {
out << ", ";
}
}
}
out << ")";
return out;
}
Then this is the main.cpp that I am using to test the SquareMatrix ADT object:
#include "SquareMatrix.h"
#include <iostream>
#include <random>
#include <ctime>
#include <vector>
using namespace std;
int main() {
srand(time(NULL));
vector<vector<double>> m1;
vector<vector<double>> m2;
int size = 0;
cout << "Enter the size of the Square Matrix: ";
cin >> size;
for (int i = 0; i < size; i++) {
vector<double> in1;
vector<double> in2;
for (int j = 0; j < size; j++) {
in1.push_back(rand() % 100);
in2.push_back(rand() % 100);
}
m1.push_back(in1);
m2.push_back(in2);
}
SquareMatrix res1 = SquareMatrix(m1);
SquareMatrix res2 = SquareMatrix(m2);
cout<< "\nMatrix 1: " << endl;
cout << res1 << endl;
cout<< "\nMatrix 2: " << endl;
cout << res2 << endl;
SquareMatrix mult = res1*res2;
cout << "\nMatrix1 * Matrix 2: " << endl;
cout << mult << endl;
SquareMatrix min1_2 = res1 - res2;
cout << "Matrix1 - Matrix 2: " << endl;
cout << min1_2 << endl;
SquareMatrix min2_1 = res2 - res1;
cout << "Matrix2 - Matrix 1: " << endl;
cout << min2_1 << endl;
return 0;
}
Any help you could give would be appreciated. :)
As pointed out in the comments, you problem is a simple typo in one of your nested loops. However, I'd like to add some recommendations to make your code less error prone (and also more readable).
Firstly, when iterating over all elements of a vector, unless you need an index for something else, you should be using a range-based for-loop. In your code, you might replace the check for square size with the following:
for (const vector<double>& vec: v2d){
if (vec.size() != v2d.size()){
flagSize = false;
break;
}
}
This expresses your intent a little more clearly, and, more importantly, prevents you from accidentally reading from/writing to a location out of your vector's bounds (accidentally typing <= instead of just < happens to the best of us).
Secondly, the two nested loops (that contained your error) can be replaced with a simple copy assignment (numMatrix = v2d; reference). Again, this expresses your intent in addition to being a whole lot shorter. No need to reinvent the wheel with functions like these.
The contents of the else-branch of the surrounding if-statement can also be replaced with a call to assign (the first overload listed on the page, use like numMatrix.assign(10, vector<double>(10, 0.0))). Like before, clearer expression of intent and avoidance of index errors.
Finally, the parameter in this constructor can be a const reference instead of a normal one since you do not alter its contents in any way (and, given this, it should be const).
You might wonder why "expression of intent" is relevant, or what it even means in this context. Essentially, it's all about making what you're trying to do immediately obvious to any reader. This is more important in large projects with many contributors but it is helpful even when debugging small applications like this one. You seem to be learning still, but I strongly believe it's a good thing to keep in mind from the beginning. After all, many of these changes also make for briefer code, making it that much easier for others to help you if you run into a problem.
I realize this left the scope of the original question somewhat, but I hope you find this helpful nonetheless.
I am having issues with the ostream operator overload. When I cout in my Main() it outputs
/ c"\progra"
Why it is outputting the file path and not the stream I created, I can not figure out. I am omitting the code that is not part of outputting the array. I am trying to loop through each element of the array and add it to a string that is in the end outputted via cout;
Main.cpp
Search test(20);
test.init_sorted();
cout << test;
Search.cpp
Search::Search(int size)
{
array_size = size;
numbers = new int[size];
}
void Search::init_sorted()
{
for (int i = 0; i < array_size; i++) {
if (i == 0) {
srand(for_srand);
numbers[i] = rand() % 5;
}
else {
srand(for_srand);
numbers[i] = numbers[i - 1] + rand() % 5;
}
}
}
ostream & operator<<(ostream & os, const Search & s)
{
string output;
for (int i = 0; i < s.array_size; i++) {
output += s.numbers[i] + " / ";
}
os << output;
return os;
}
Search.h
class Search
{
private:
int array_size;
int *numbers;
int for_srand = 10;
public:
Search(int);
~Search();
friend ostream& operator<<(ostream& os, const Search& dt);
};
Undefined behaviour. Due to pointer arithmetic,
output += s.numbers[i] + " / ";
is the same as
output += " / "[s.numbers[i]];
Also, it's not going to format any number:
for (int i = 0; i < s.array_size; i++) {
out << s.numbers[i] << " / ";
}
That being said, unless you know what you're doing, use standard containers and algorithms, e.g. std::vector<int> instead of int*.
I am trying to run the following code on c++ but keep geting error. Can anyone solve it for me please.
the error message from c++ says:
Error 6 error C2679: binary '<<' : no operator found which takes a
right-hand operand of type 'MVector'
#include <iostream>
#include <cmath>
#ifndef MVECTOR_H // the 'include guard'
#define MVECTOR_H // see C++ Primer Sec. 2.9.2
#include <vector>
#include <string>
#include <fstream>
class MVector
{
public:
// constructors
MVector() {}
explicit MVector(int n) : v(n) {}
MVector(int n, double x) : v(n, x) {}
void push_back(double x)
{
v.push_back(x);
}
double AV()
{
double sum = 0.0, average = 0.0;
for (double i = 0; i<v.size(); i++)
{
sum += v[i];
}
average = sum / v.size();
return average;
}
MVector RunningAverage(int m, int p)
{
MVector movingaverage(v.size() - m - p - 1);
for (int i = m; i < v.size() - p; i++)
{
double sum = 0.0;
if ((i + p < v.size()))
{
for (int j = i - m; j <= i + p; j++)
{
sum += v[j];
movingaverage[i - m] = sum / (m + p + 1);
}
}
}
return movingaverage; // Edit by jpo38
}
// access element (lvalue)
double &operator[](int index) { return v[index]; }
// access element (rvalue)
double operator[](int index) const { return v[index]; }
int size() const { return v.size(); } // number of elements
private:
std::vector<double> v;
};
#endif
int main()
{
using namespace std;
// create an MVector
MVector x;
// add elements to the vector
x.push_back(1.3);
x.push_back(3.5);
x.push_back(3.0);
x.push_back(2.0);
// x now contains 1.3 and 3.5
// print x
std::cout << " x:= ( ";
for (int i = 0; i < x.size(); i++)
std::cout << x[i] << " ";
std::cout << ")\n";
std::cout << x.RunningAverage(0, 1.0) << endl;
return 0;
}
x.RunningAverage(0, 1.0) returns a MVector that cannot be sent to std::cout, unless you declare the operator<< taking a MVector as parameter.
Alternatively, you can replace:
std::cout << x.RunningAverage(0, 1.0) << endl;
By:
MVector av = x.RunningAverage(0, 1.0);
for (int i = 0; i < av.size(); i++)
std::cout << av[i] << " ";
Or, declare the operator:
std::ostream& operator<<(std::ostream& out,const MVector& b)
{
for (int i = 0; i < b.size(); i++)
out << b[i] << " ";
return out;
}
And then std::cout << x.RunningAverage(0, 1.0) << std::endl; will work.
And you can then also replace, in your main function:
for (int i = 0; i < x.size(); i++)
std::cout << x[i] << " ";
By:
std::cout << x;
Live demo: http://cpp.sh/7afyi
You haven't overloaded operator<< for MVector.
You can do that with:
std::ostream& operator<<(std::ostream& output, MVector const& vec)
{
// use "output << …;" to do printing
return output;
}
I'm trying to figure out why my program fails when I run. So far when I run my program it fails on me. I debugged the error and it brings me to dbgdel.cpp. Line 32 " _ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));". I've searched for the answer to no avail, but it has something to do with my memory leak?
Here is my header:
#include <iostream>
using namespace std;
namespace project
{
#ifndef MATRIX_H
#define MATRIX_H
typedef int* IntArrayPtr;
class Matrix
{
public:
friend ostream& operator<<(ostream& out, Matrix& object);
//friend istream& operator>>(istream& in, Matrix& theArray);
//Default Constructor
Matrix();
Matrix(int max_number_rows, int max_number_cols, int intial_value);
//Destructor
~Matrix();
//Copy Constructor
Matrix(const Matrix& right_side);
//Assignment Operator
Matrix& operator=(const Matrix& right_side);
void Clear();
int Rows();
int Columns();
bool GetCell(int x,int y, int& val);
bool SetCell(int x,int y, int val);
int getNumber(int r, int c);
//void Debug(ostream& out);
private:
int initialVal;
int rows;
int cols;
IntArrayPtr *m;
};
#endif
}
My implementation file:
#include <iostream>
#include "Matrix.h"
using namespace project;
using namespace std;
namespace project
{
Matrix::Matrix()
{
typedef int* IntArrayPtr;
IntArrayPtr *m = new IntArrayPtr[1];
for(int i = 0; i < 1; i++)
m[i] = new int[1];
for(int r = 0; r < 1; r++)
for(int c = 0; c < 1;c++)
m[r][c] = 0;
}
Matrix::Matrix(int max_number_rows, int max_number_cols, int initial_value)
{
initialVal = initial_value;
rows = max_number_rows;
cols = max_number_cols;
IntArrayPtr *m = new IntArrayPtr[rows];
for(int i = 0; i < rows; i++)
m[i] = new int[cols];
for(int r = 0; r < max_number_rows; r++)
for(int c = 0; c < max_number_cols;c++)
m[r][c] = initial_value;
}
Matrix::~Matrix()
{
for(int i = 0; i <= rows; i++)
delete [] m[i];
delete [] m;
}
void Matrix::Clear()
{
for(int r = 0; r < rows; r++)
for(int c = 0; c < cols;c++)
m[r][c] = initialVal;
}
int Matrix::Rows()
{
return rows;
}
int Matrix::Columns()
{
return cols;
}
bool Matrix::GetCell(int x,int y, int& val)
{
if(x < rows || y < cols)
return false;
else
{
val = m[x - 1][y - 1];
return true;
}
}
bool Matrix::SetCell(int x, int y, int val)
{
if(x < rows || y < cols)
return false;
else
{
m[x - 1][y - 1] = val;
return true;
}
}
int Matrix::getNumber(int r, int c)
{
return m[r][c];
}
ostream& operator<<(ostream& out, Matrix& object)
{
for(int r = 0; r < object.rows; r++)
{
for(int c = 0; c < object.cols; c++)
{
out << " " << object.m[r][c];
}
out << endl;
}
return out;
}
Matrix& Matrix::operator=(const Matrix& right_side)
{
if (this != &right_side)
{
rows = right_side.rows;
cols = right_side.cols;
delete[] m;
IntArrayPtr *m = new IntArrayPtr[rows];
for(int i = 0; i < rows; i++)
m[i] = new int[cols];
for(int r = 0; r < rows; r++)
for(int c = 0; c < cols;c++)
m[r][c] = right_side.initialVal;
}
return *this;
}
/*
void Matrix::Debug(ostream& out)
{
out << "Number of rows = " << rows << endl;
out << "Number of columns = " << cols << endl;
out << "Initializer = " << initialVal << endl;
out << "Current contents of the matrix: " << endl;
out << m << endl;
}
*/
/*
istream& operator >>(istream& in, Matrix& theArray)
{
in >>
}
void interfaceMatrix()
{
int userChoice, rows, columns, value;
cout << "Default matrix or custom(1 for default, 0 for custom): ";
cin >> userChoice;
if (userChoice == 1)
{
Matrix object;
return object;
}
else if(userChoice == 0)
{
cout << "Enter number of rows: ";
cin >> rows;
cout << "Enter number of columns: ";
cin >> columns;
cout << "Enter initial value of each element: ";
cin >> value;
if(rows <= 0 || columns <= 0)
{
cout << "Invalid input." << endl;
exit(1);
}
else
{
Matrix object(rows, columns, value);
return object;
}
}
else
{
cout << "Invalid choice." << endl;
exit(1);
}
}
*/
}
In my driver I just put Matrix test(2,2,2), so I can create a 2 x 2 array with initial value of 2 for each element. I get the above error.
You are allocating rows number of rows, but deallocating rows+1 number of rows.
Check the destructor. <= must be <.
Besides this there are a lot of other [potential] errors in your code:
you are setting the local m variable instead of setting the m data member of your class (that's why I have the convention to always precede data members by m_ to prevent this kind of confusion). This error appears both in the constructor and the assignment operator.
you use rows to allocate the matrix, but max_number_rows to initialize the matrix. Although it works correctly now, it may lead to errors if row is initialized differently later (e.g. if row is initialized with std::max(max_number_rows,1000). Your code in the assignment operator is better.
your if-test in GetCell and SetCell is incorrect. It should probably be >= instead of <
the assignment operator copies the size of the matrix, but assigns all cells an initialValue. This is not an assignment. This implementation might/will confuse the rest of the code.
the typedef of IntArrayPtr is unnecessary
two issues:
You are not allocating any value into the "m" member of your object, you are allocating into local variables named "m"
you are over deallocating by looping from i=0 to i <= rows, you want i=0 to i < rows
I am trying to overload the ostream << operator in my Matrix class, but I keep getting the following error:
Expected constructor, destructor, or type conversion before token &
Matrix::ostream& operator<<(const Matrix& matrix)
{
for (int r = 0; r < matrix.getNumrows(); r++)
{
cout << matrix.getPoint(r, 0);
for (int c = 0; c < matrix.getNumcolumns(); c++)
{
cout << " " << matrix.getPoint(r,c);
}
cout << endl;
}
return stream;
}
This is the rest of my class
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include "Matrix.h"
using namespace std;
Matrix::Matrix()
{
}
Matrix::Matrix(int rows, int cols) {
numRows=rows;
numCols=cols;
//col=new double[cols];
mx=new double*[rows];
for ( int i=0; i < rows; i++ ) {
mx[i] = new double[cols];
// initalize each element of the new row.
for ( int c=0; c < cols; c++ ) {
mx[i][c] = 0.0;
}
}
}
Matrix::Matrix(const Matrix &theMatrix) {
int rows=theMatrix.numRows;
int cols=theMatrix.numCols;
numRows = rows;
numCols = cols;
mx=new double*[rows];
for ( int r=0; r < rows; r++ ) {
mx[r] = new double[cols];
// copy each element of the new row.
for ( int c=0; c < cols; c++ ) {
mx[r][c] = theMatrix.mx[r][c];
}
}
}
void Matrix::setMatrix(string file)
{
/* read the file */
fstream inputStream(file.c_str());
if(inputStream.is_open() )
{
string line;
stringstream ss;
getline(inputStream, line);
ss.clear();
ss.str(line);
ss >> numRows >> numCols;
mx=new double*[numRows];
for ( int i=0; i < numRows; i++ ) {
mx[i] = new double[numCols];
// initalize each element of the new row.
for ( int c=0; c < numCols; c++ ) {
mx[i][c] = 0.0;
}
}
//now loop to get values
for(int row=0; row<numRows; row++)
{
getline(inputStream, line);
ss.clear();
ss.str(line);
//now get every value in the line
for(int col=0; col<numCols; col++)
{
double current;
ss >> current;
mx[row][col] = current;
}//end reading values of row
}//end reading rows
}
//close the file
inputStream.close();
}
int Matrix::getNumrows()
{
return numRows;
}
int Matrix::getNumcolumns()
{
return numCols;
}
void Matrix::printPoint()
{
for ( int r=0; r < numRows; r++ )
{
for ( int c=0; c < numCols; c++ )
{
cout << mx[r][c] << " ";
}
cout << endl;
}
cout << endl;
}
bool Matrix::getIsSquared()
{
if( numRows == numCols )
{
return true;
}
else
{
return false;
}
}
double Matrix::det()
{
double det=0.0;
if(numRows!=numCols)
{
cout << "Number Rows must be same as number Colums\n";
}
if(numRows==2)
{
det=(mx[0][0]*mx[1][1])-(mx[0][1]*mx[1][0]);
}
else
{
for(int i=0 ; i<numCols ; i++)
{
Matrix temp(numRows-1,numCols-1);
for(int j=0 ; j<numRows-1 ; j++)
{
for(int k=0 ; k<numCols-1 ; k++)
{
if(k<i)
temp.mx[j][k]=mx[j+1][k];
else
temp.mx[j][k]=mx[j+1][k+1];
}
}
det+=pow(-1.0,i)*mx[0][i]*temp.det();
}
}
return det;
}
double Matrix::getPoint(int row, int col)
{
return mx[row][col];
}
Matrix Matrix::operator +(const Matrix &right) const
{
Matrix result(numRows,numCols);
if ( right.numRows != numRows || right.numCols != numCols )
{
cout << "\nError while adding matricies, the two must have the same dimentions.\n";
}
else
{
for ( int r=0; r < numRows; r++ )
{
for ( int c=0; c < numCols; c++ )
{
result.mx[r][c] = (this->mx[r][c]) + (right.mx[r][c]);
}
}
}
return result;
}
If you want to overload the ostream operator<< for your class, you need to use either a friend function or a non-member function because the ostream object appears on the left-hand side of the expression (it's written as os << my_matrix).
std::ostream& operator<<(std::ostream& os, const Matrix& matrix) { /* ... */ }
It looks like you are trying to implement it as a member function, but that should actually look like:
std::ostream& Matrix::operator<<(const Matrix& matrix) { /* ... */ }
This won't work because when you implement an operator overload as a member function, the type of the object on the left hand side of the expression is the same as the type of the class of which the overload is a member (so, in this case, you'd have to write my_matrix1 << my_matrix2, which isn't what you want).
Inside of the overload, you shouldn't write to cout directly; you should write to the ostream object that is passed as an argument to the function.
Write it as:
ostream& operator<<(ostream& os, const Matrix& matrix)
{
for (int r = 0; r < matrix.getNumrows(); r++)
{
os << matrix.getPoint(r, 0);
for (int c = 0; c < matrix.getNumcolumns(); c++)
{
os << " " << matrix.getPoint(r,c);
}
os << endl;
}
return os;
}
and it will work. It does not have to be a member function of Matrix.
Just change
Matrix::ostream& operator<<(const Matrix& matrix)
to
std::ostream& operator<< (std::ostream &stream, const Matrix &matrix)
It'll be a stand-alone function .. and should work just fine.