Why isnt my simpleVector.cpp linking? (starting out with c++) - c++

i got the .cpp and .h straight from the book, it seems as if nothing is missing, but im getting these linking errors....
#ifndef SIMPLEVECTOR_H
#define SIMPLEVECTOR_H
#include <iostream>
#include <new> // needed for bad__alloc exception
#include <cstdlib> // needed for the exit function
using namespace std;
template <class T>
class simplevector
{
private:
T *aptr;
int arraysize;
void memerror(); // handles mem aloc errors
void suberror(); // handles subscripts out of range
public:
simplevector() // default constructor
{ aptr = 0; arraysize = 0; }
simplevector(int); // constructor
simplevector(const simplevector &); // coppy constructor
~simplevector();
int size()
{ return arraysize; }
T &operator[](const int &); // overloaded [] operator
};
template <class T>
simplevector<T>::simplevector(int s)
{
arraysize = s;
// allocate memory for the array
try
{
aptr = new T [s];
}
catch (bad_alloc)
{
memerror();
}
// initialize the array.
for (int count = 0; count < arraysize; count++)
*(aptr + count) = 0;
}
template <class T>
simplevector<T>::simplevector(const simplevector &obj)
{
arraysize = obj.arraysize;
aptr = new T [arraysize];
if (aptr == 0)
memerror();
for(int count = 0; count < arraysize; count++)
*(aptr + count) = *(obj.aptr + count);
}
template <class T>
simplevector<T>::~simplevector()
{
if (arraysize > 0)
delete [] aptr;
}
template <class T>
void simplevector<T>::memerror()
{
cout << "ERROR: Cannot allocate memory.\n";
exit(0);
}
template <class T>
T &simplevector<T>::operator [](const int &sub)
{
if (sub < 0 || sub >= arraysize)
suberror();
return aptr[sub];
}
#endif
This program demonstrates the simplevector template:
#include <iostream>
#include "simplevector.h"
using namespace std;
int main()
{
simplevector<int> inttable(10);
simplevector<float> floattable(10);
int x;
//store values in the arrays.
for (x = 0; x < 10; x++)
{
inttable[x] = (x * 2);
floattable[x] = (x * 2.14);
}
//display the values in the arrays.
cout << "these values are in inttable:\n";
for (x = 0; x< 10; x++)
cout << inttable[x] << " ";
cout << endl;
cout << "these values are in floattable:\n";
for (x = 0; x< 10; x++)
cout << floattable[x] << " ";
cout << endl;
//use the standard + operator on array elements.
cout << "\nAdding 5 to each element of inttable"
<< " and floattable.\n";
for (x = 0; x< 10; x++)
{
inttable[x] = inttable[x] + 5;
floattable[x] = floattable[x] + 1.5;
}
//display the values in the array.
cout << "These values are in inttable:\n";
for (x = 0; x< 10; x++)
cout << inttable[x] << " ";
cout << endl;
cout << "These values are in floattable:\n";
for (x = 0; x< 10; x++)
cout << floattable[x] << " ";
cout << endl;
// use the standard ++ operator on array elements.
cout << "\nIncrementing each element of inttable and"
<< " floattable.\n";
for (x = 0; x< 10; x++)
{
inttable[x]++;
floattable[x]++;
}
//display the values in the array.
cout << "These values are in inttable:\n";
for (x = 0; x< 10; x++)
cout << inttable[x] << " ";
cout << endl;
cout << "These values are in floattable:\n";
for (x = 0; x< 10; x++)
cout << floattable[x] << " ";
cout << endl;
return 0;
}

It's right there in the errors you posted in the OP comments - you declared simplevector::suberror without ever defining it.

Where are the guts of suberror()? I don't see that in the class implementation.

Related

Iterator design pattern for 2d vector c++, OOP

I'm beginner in C++. In my program I've created a matrix and wrote some func to operate with its cols and rows. Instead of i and j counters i want to implement iterator design pattern Didn't find proper info here. Can you pls help me with this task? Here is my code:
#include <iostream>
#include <iomanip>
#include <vector>
using namespace std;
#define C 5
template <class T>
class myMatrix
{
private:
int col, row;
vector<vector<T>> matrix;
public:
myMatrix(int a, int b)
{
col = b;
row = a;
matrix.assign(a, vector<T>(b));
}
void copy_row(int numb);
void copy_col(int numb);
void input();
void output();
~myMatrix() { }
};
template <class T>
void myMatrix<T>::copy_row(int numb)
{
for (int i = 0; i < col; i++)
cout << matrix[numb][i] << " ";
}
template <class T>
void myMatrix<T>::copy_col(int numb)
{
for (int i = 0; i < row; i++)
cout << matrix[i][numb] << endl;
}
template <class T>
void myMatrix<T>::input()
{
for (int i = 0; i < row; i++)
for (int j = 0; j < col; j++)
{
T number;
cin >> matrix[i][j];
}
}
template <class T>
void myMatrix<T>::output()
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
cout << setw(10) << left << matrix[i][j];
cout << endl;
}
cout << endl;
}
int main()
{
int a, b;
myMatrix<int> matrix1(5, 5);
cout << "Put in the matrix 5x5: " << endl;
matrix1.input();
cout << endl;
matrix1.output();
cout << "Put the column number to copy: ";
cin >> a;
cout << endl;
matrix1.copy_col(a - 1);
cout << endl;
cout << "Put the row number to copy: ";
cin >> b;
cout << endl;
matrix1.copy_row(b - 1);
cout << endl;
return 0;
}

Heap sort and insertion sort

I want to make a c++ program that runs two algorithms - insertion and heap sort. But I keep getting an error that array size must have integral or enumeration type, not double. Where are my mistakes? I'm reading data from file.
#include "stdafx.h"
#include <stdio.h>
#include <tchar.h>
#include <random>
#include <fstream>
#include <iostream>
#include <algorithm>
#include <time.h>
void generuoti(int _N, const char *_file);
void nuskaityti(const char *_file);
void sortInsertion(double A[], int N);
void heapSort(double A[], int N);
void heapify(double A[], int N, int i);
using namespace std;
double *Data;
double* A;
double* B;
double* A1;
double* B1;
double N;
unsigned long int palyginimai1 = 0;
unsigned long int priskyrimai1 = 0;
unsigned long int palyginimai2 = 0;
unsigned long int priskyrimai2 = 0;
int main()
{
srand(time(NULL));
cout << "generuojame atsitktinius duomenis ..." << endl;
generuoti(106000, "duom.txt");
cout << "nuskaitome duomenis ..." << endl;
nuskaityti("duom.txt");
A = new double[N];
B = new double[N];
A1 = new double[N];
B1 = new double[N];
for (int i = 0; i < N; i++) {
A[i] = Data[i];
}
//cout << "Heap array:" << endl;
for (int i = 0; i < N; i++)
//cout << A[i] << " ";
//cout << endl;
//cout << "Insertion array: " << endl;
for (int i = 0; i < N; i++)
{
B[i] = A[i];
//cout << B[i] << " ";
}
for (int i = 0; i < N; i++)
{
A1[i] = A[i];
B1[i] = B[i];
}
//cout << endl;
int nUntil = 2000;
while (nUntil <= 106000)
{
sortInsertion(B1, nUntil);
heapSort(A1, nUntil);
cout << priskyrimai1 << endl;
nUntil = nUntil * 2;
for (int i = 0; i < N; i++)
{
A1[i] = A[i];
B1[i] = B[i];
}
//cout << nUntil << palyginimai2 << " " << priskyrimai2 << endl;
}
/*cout << "Surusiuota skaiciu seka Heap:" << endl;
for (int i = 0; i < N; i++)
cout << A1[i] << " ";
cout << endl;
cout << "Surusiuota skaiciu seka Insertion:" << endl;
for (int i = 0; i < N; i++)
cout << B1[i] << " ";
cout << endl;*/
system("pause");
return 0;
}
void generuoti(int _N, const char *_file) {
ofstream os(_file);
os << _N << endl;
for (int i = 0; i < _N; i++)
{
os << " " << (double)(rand() % 1001) / (double)1000;
}
//os << " " << (double)13 << " " << (double)18 << " " << (double)25 << " " << (double)2 << " " << (double)6 << " " << (double)11 << " " << (double)16 << " " << (double)1 << " " << (double)6 << " " << (double)21 << " " << (double)17;
os.close();
}
void nuskaityti(const char *_file) {
ifstream is(_file);
if (is.fail()) {
cout << "failo nera" << endl;
exit(1);
}
is >> N;
Data = new double[N];
for (int i = 0; i < N; i++) {
is >> Data[i];
}
}
void sortInsertion(double A[], int N) {
double temp;
int hole;
for (int i = 1; i < N; i++)
{
palyginimai1++;
temp = A[i];
hole = i;
while (hole > 0 && A[hole - 1] > temp)
{
palyginimai1++;
A[hole] = A[hole - 1];
priskyrimai1++;
hole--;
}
priskyrimai1++;
A[hole] = temp;
}
}
void heapify(double A[], int N, int i)
{
int largest = i;
int l = 2 * i + 1;
int r = 2 * i + 2;
priskyrimai2 = priskyrimai2 + 3;
if (l < N && A[l] > A[largest])
{
largest = l;
priskyrimai2++;
}
if (r < N && A[r] > A[largest])
{
largest = r;
priskyrimai2++;
}
if (largest != i)
{
swap(A[i], A[largest]);
heapify(A, N, largest);
palyginimai2++;
priskyrimai2++;
}
}
void heapSort(double A[], int N)
{
for (int i = N / 2 - 1; i >= 0; i--)
{
heapify(A, N, i);
palyginimai2++;
}
for (int i = N - 1; i >= 0; i--)
{
swap(A[0], A[i]);
priskyrimai2++;
heapify(A, i, 0);
palyginimai2++;
}
}
Also, I'm counting palyginimai - comparisons, priskyrimai-assignments.
A quick solution would be to replace anywhere you use the subscript([]) operator do this instead: A = new double[(int)N];
I hope this helps.

Issue with array index out of bounds assignment

I have seen several articles regarding something similar but none of them seem to help me. I would appreciate if someone could look at my code and tell me what I am doing wrong here. My teacher is not helping much. I commented out lines 65 - 75 in the driver because i couldn't get it to compile with these, will need help with this as well
ArrayDriver.cpp
#include <iostream>
#include "myArray.h"
using namespace std;
int main()
{
myArray<int> list1(5);
myArray<int> list2(5);
int i;
cout << "list1 : ";
for (i = 0 ; i < 5; i++)
cout << list1[i] <<" ";
cout << endl;
cout << "Enter 5 integers: ";
for (i = 0 ; i < 5; i++)
cin >> list1[i];
cout << endl;
cout << "After filling list1: ";
for (i = 0 ; i < 5; i++)
cout << list1[i] <<" ";
cout<< endl;
list2 = list1;
cout << "list2 : ";
for (i = 0 ; i < 5; i++)
cout << list2[i] <<" ";
cout<< endl;
cout << "Enter 3 elements: ";
for (i = 0; i < 3; i++)
cin >> list1[i];
cout << endl;
cout << "First three elements of list1: ";
for (i = 0; i < 3; i++)
cout << list1[i] << " ";
cout << endl;
myArray<int> list3(-2, 6);
cout << "list3: ";
for (i = -2 ; i < 6; i++)
cout << list3[i] <<" ";
cout<< endl;
list3[-2] = 7;
list3[4] = 8;
list3[0] = 54;
list3[2] = list3[4] + list3[-2];
cout << "list3: ";
for (i = -2 ; i < 6; i++)
cout << list3[i] <<" ";
cout<< endl;
/*
if (list1 == list2)
cout << " list 1 is equal to list2 " << endl;
else
cout << " list 1 is not equal to list2" << endl;
if (list1 != list2)
cout << " list 1 is not equal to list2 " << endl;
else
cout << " list 1 is equal to list2" << endl;
*/
//10% EXTRA CREDIT: UNCOMMENT CODE IF YOU'VE SUCCESSFULLY IMPLEMENTED THE FOLLOWING:
//cout << list1<< (list1 == list2 ? " is equal to" : " not equal to ") << list2 << endl;
//cout << list1<< (list1 != list2 ? " not equal to" : " is equal to ") << list2 << endl;
return 0;
}
myArray.h
#ifndef MYARRAY_H
#define MYARRAY_H
//#pragma once
#include <iostream>
//#include <assert.h>
//#include <iomanip>
//#include <string>
using namespace std;
template <class DataType>
class myArray
{
//overload for <<
//friend ostream& operator<<(ostream& out, myArray<DataType>& arr);
//overload for >>
friend istream& operator>>(istream& in, myArray<DataType>& arr);
public:
//myArray();
myArray(int size);
myArray(int start, int end);
//~myArray();
//overload []
DataType& operator[](int i);
//overload == operator
friend bool operator==(myArray<DataType> &arr1, myArray<DataType> &arr2);
//overload != operator
friend bool operator!=(myArray<DataType> &arr1, myArray<DataType> &arr2);
//overload = opertator
myArray<DataType> &operator=(const myArray<DataType> &rhs)
{
if (myDataType != NULL)
delete[]myDataType;
myDataType = new DataType[rhs.arraySize];
arraySize = rhs.arraySize;
for (int i = 0; i < arraySize; i++)
myDataType[i] = rhs.myDataType[i];
return *this;
}
//function
void SetNULL();
protected:
int startIndex;
int endIndex;
int arraySize;
//template
DataType *myDataType;
};
#endif
template <class DataType>
DataType& myArray<DataType>::operator[](int i)
{
if (i > arraySize)
{
cout << "Array out of bounds: " << endl;
}
else if (startIndex == 0)
{
return myDataType[i];
}
else
{
return myDataType[(startIndex + (i - 1))];
}
}
template <class DataType>
myArray<DataType>::myArray(int size) :
arraySize(size), startIndex(0), endIndex(size)
{
myDataType = new DataType[arraySize];
SetNULL();
}
template <class DataType>
myArray<DataType>::myArray(int start, int end) :
startIndex(start), endIndex(end)
{
if (start > end)
{
cout << "Invalid start position: " << endl;
}
else
{
arraySize = end - start;
}
myDataType = new DataType[arraySize];
SetNULL();
}
template <class DataType>
void myArray<DataType>::SetNULL()
{
for (int i = startIndex; i < endIndex; i++)
{
myDataType[i] = (DataType)0;
}
}
//overload == operator
template <class DataType>
bool operator==(myArray<DataType> &arr1, myArray<DataType> &arr2)
{
bool testBool = true;
for (int i = 0; i < arraySize; i++)
{
if (arr1[i] != arr2[i])
{
testBool = false;
}
}
return testBool;
}
//overload != operator
template <class DataType>
bool operator!=(myArray<DataType> &arr1, myArray<DataType> &arr2)
{
bool testBool = true;
for (int i = 0; i < arraySize; i++)
{
if (arr1[i] == arr2[i])
{
testBool = false;
}
}
return testBool;
}
//overload >> operator
template <class DataType>
istream& operator>> (istream &in, myArray<DataType> &aList)
{
for (int i = 0; i < aList.arraySize; i++)
in >> aList.list[i];
return in;
}
That's why not ignoring warnings (or using debugger) is helpful. My compiler showed the issue (via warnings), which should be the culprit of your problem.
In function:
myArray<DataType> &operator=(const myArray<DataType> &rhs)
{
if (myDataType = NULL)
delete[]myDataType;
myDataType = new DataType[rhs.arraySize];
arraySize = rhs.arraySize;
for (int i = 0; i < arraySize; i++)
myDataType[i] = rhs.arraySize;
return *this;
}
UPDATE: You are also assigning the array size as elements of your newly created copy. Copy actual elements.
UPDATE #2: As pointed out by fellow commenters, you also forgot to check for self-assignment. Check if the array pointer of your current array is equal to the one you are assigning.
you are doing an assignment instead of comparison in the first if statement. Consider doing this:
myArray<DataType> &operator=(const myArray<DataType> &rhs)
{
if (myDataType == rhs.myDataType) //CHECK IF THE ARRAY IS THE SAME (self-assignment case).
return *this;
// Missing '!' character here!!!
if (myDataType != NULL)
delete[]myDataType;
myDataType = new DataType[rhs.arraySize];
arraySize = rhs.arraySize;
for (int i = 0; i < arraySize; i++)
myDataType[i] = rhs.myDataType[i]; // COPY ACTUAL ELEMENTS INSTEAD OF WRITTING ARRAY SIZE.
return *this;
}
And, to avoid such issues in the future (if your compiler doesn't pick up on issues like this, consider doing comparisons, with constant values, like this:
if (NULL != myDataType)
delete[]myDataType;
And then your compiler will, no matter what, pick up on the issue, since it can't assign to a constant value.
UPDATE #3: Also, as I noticed, you are also allowing for arrays to have user defined start/end indexes. But, you would need to rethink your current approach of calculating the index at which to get the elements in such a case (where startIndex != 0). You are getting the position of element with formula: 'startIndex + (i - 1)'. But in your test case, in list3, where the range of indexes is [-2; 6), and you start your for loop, the initial index equates to -2 + (-2 - 1) = -2 - 3 = -5. I am not sure why your code isn't crashing here, but it should.
Also, to implement the comparisons operators, check if the size is the same at first, since if one of the arrays is smaller, and you are iterating through the indexes of the larger one, it should crash, when you will access the non-existing index (and to be honest, if sizes of arrays differ - they are not equal, are they?).

Matrix Overload C++

In the header file I am suppose to add the declaration of functions which I need to overload operators. Then implement the functions I added into the header file.
Can any one help me with what I am suppose to do? Please explain so I can wrap my head around overloading if possible.
I have listed the code below. As for main I am not suppose to edit it.
Header File
Matrix.h
#ifndef MATRIX_H
#define MATRIX_H
class Matrix
{
public:
Matrix (int sizeX, int sizeY);
~Matrix();
int GetSizeX() const { return dx; }
int GetSizeY() const { return dy; }
long &Element(int x, int y); // return reference to an element
void Print () const;
private:
long **p; // pointer to a pointer to a long integer
int dx, dy;
};
#endif /* MATRIX_H */
Matrix.cpp File
#include <iostream>
#include <cassert>
#include "Matrix.h"
using namespace std;
Matrix::Matrix (int sizeX, int sizeY) : dx(sizeX), dy(sizeY)
{
assert(sizeX > 0 && sizeY > 0);
p = new long*[dx];
// create array of pointers to long integers
assert(p != 0);
for (int i = 0; i < dx; i++)
{ // for each pointer, create array of long integers
p[i] = new long[dy];
assert(p[i] != 0);
for (int j = 0; j < dy; j++)
p[i][j] = 0;
}
}
Matrix::~Matrix()
{
for (int i = 0; i < dx; i++)
delete [] p[i]; // delete arrays of long integers
delete [] p; // delete array of pointers to long
}
long &Matrix::Element(int x, int y)
{
assert(x >= 0 && x < dx && y >= 0 && y < dy);
return p[x][y];
}
void Matrix::Print () const
{
cout << endl;
for (int x = 0; x < dx; x++)
{
for (int y = 0; y < dy; y++)
cout << p[x][y] << "\t";
cout << endl;
}
}
main.cpp
#include <cstdlib>
#include <iostream>
#include <cassert>
#include <ctime>
#include "Matrix.h"
using namespace std;
int main(int argc, char** argv) {
int size1, size2, size3;
const int RANGE = 5; //using to generate random number in the range[1,6]
cout << "Please input three positive integers: (size)";
cin >> size1 >> size2 >> size3;
assert(size1 > 0 && size2 > 0 && size3 > 0);
Matrix myMatrix1(size1, size2), myMatrix2(size2,size3);
Matrix yourMatrix1(size1, size2), yourMatrix2(size2, size3);
Matrix theirMatrix1(size1, size2), theirMatrix2(size1, size3);
srand(time(0));
for (int i = 0; i < size1; i++)
for (int j = 0; j < size2; j++)
myMatrix1(i,j) = rand() % RANGE + 1;
yourMatrix1 = 2 * myMatrix1;
theirMatrix1 = myMatrix1 + yourMatrix1;
cout << "myMatrix1: " << endl;
cout << myMatrix1 << endl << endl;
cout << "yourMatrix1 = 2 * myMatrix " << endl;
cout << yourMatrix1 << endl << endl;
cout << "myMatrix1 + yourMatrix1: " << endl;
cout << theirMatrix1 << endl << endl;
for (int i = 0; i < size2; i++)
for (int j = 0; j < size3; j++)
myMatrix2(i,j) = rand() % RANGE + 1;
yourMatrix2 = myMatrix2 * 3;
theirMatrix2 = myMatrix1 * yourMatrix2;
cout << "myMatrix1: " << endl;
cout << myMatrix1 << endl << endl;
cout << "myMatrix2: " << endl;
cout << myMatrix2 << endl << endl;
cout << "yourMatrix2 = myMatrix2 * 3 " << endl;
cout << yourMatrix2 << endl << endl;
cout << "myMatrix1 * yourMatrix2: " << endl;
cout << theirMatrix2 << endl << endl;
return 0;
}
You need to look into the main and see what all operators are used with the Matrix objects. You have to overload those operators into the Matrix class given to you i.e. write member functions into this class.
Refer following link for details on operator overloading with examples:
http://en.wikibooks.org/wiki/C%2B%2B_Programming/Operators/Operator_Overloading

Passing 2D array to a Function in c++

I am Having Problem with Passing a 2D array to a c++ Function. The function is supposed to print the value of 2D array. But getting errors.
In function void showAttributeUsage(int)
Invalid types for int(int) for array subscript.
I know the problem is with the syntax in which I am passing the particular array to function but I don't know how to have this particular problem solved.
Code:
#include <iostream>
using namespace std;
void showAttributeUsage(int);
int main()
{
int qN, aN;
cout << "Enter Number of Queries : ";
cin >> qN;
cout << "\nEnter Number of Attributes : ";
cin >> aN;
int attVal[qN][aN];
cout << "\nEnter Attribute Usage Values" << endl;
for(int n = 0; n < qN; n++) { //for looping in queries
cout << "\n\n***************** COLUMN " << n + 1 << " *******************\n\n";
for(int i = 0; i < aN; i++) { //for looping in Attributes
LOOP1:
cout << "Use(Q" << n + 1 << " , " << "A" << i + 1 << ") = ";
cin >> attVal[n][i];
cout << endl;
if((attVal[n][i] > 1) || (attVal[n][i] < 0)) {
cout << "\n\nTHE VALUE MUST BE 1 or 0 . Please Re-Enter The Values\n\n";
goto LOOP1; //if wrong input value
}
}
}
showAttributeUsage(attVal[qN][aN]);
cout << "\n\nYOUR ATTRIBUTE USAGE MATRIX IS\n\n";
getch();
return 0;
}
void showAttributeUsage(int att)
{
int n = 0, i = 0;
while(n != '\0') {
while(i != '\0') {
cout << att[n][i] << " ";
i++;
}
cout << endl;
n++;
}
}
I really suggest to use std::vector : live example
void showAttributeUsage(const std::vector<std::vector<int>>& att)
{
for (std::size_t n = 0; n != att.size(); ++n) {
for (std::size_t i = 0; i != att.size(); ++i) {
cout << att[n][i] << " ";
}
cout << endl;
}
}
And call it that way:
showAttributeUsage(attVal);
Looking at your code, I see no reason why you can't use std::vector.
First, your code uses a non-standard C++ extension, namely Variable Length Arrays (VLA). If your goal is to write standard C++ code, what you wrote is not valid standard C++.
Second, your initial attempt of passing an int is wrong, but if you were to use vector, your attempt at passing an int will look almost identical if you used vector.
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
typedef std::vector<int> IntArray;
typedef std::vector<IntArray> IntArray2D;
using namespace std;
void showAttributeUsage(const IntArray2D&);
int main()
{
int qN, aN;
cout << "Enter Number of Queries : ";
cin >> qN;
cout << "\nEnter Number of Attributes : ";
cin >> aN;
IntArray2D attVal(qN, IntArray(aN));
//... Input left out ...
showAttributeUsage(attVal);
return 0;
}
void showAttributeUsage(const IntArray2D& att)
{
for_each(att.begin(), att.end(),
[](const IntArray& ia) {std::copy(ia.begin(), ia.end(), ostream_iterator<int>(cout, " ")); cout << endl;});
}
I left out the input part of the code. The vector uses [] just like a regular array, so no code has to be rewritten once you declare the vector. You can use the code given to you in the other answer by molbdnilo for inputing the data (without using the goto).
Second, just to throw it into the mix, the showAttributeUsage function uses the copy algorithm to output the information. The for_each goes throw each row of the vector, calling std::copy for the row of elements. If you are using a C++11 compliant compiler, the above should compile.
You should declare the function like this.
void array_function(int m, int n, float a[m][n])
{
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
a[i][j] = 0.0;
}
where you pass in the dimensions of array.
This question has already been answered here. You need to use pointers or templates. Other solutions exists too.
In short do something like this:
template <size_t rows, size_t cols>
void showAttributeUsage(int (&array)[rows][cols])
{
for (size_t i = 0; i < rows; ++i)
{
std::cout << i << ": ";
for (size_t j = 0; j < cols; ++j)
std::cout << array[i][j] << '\t';
std::cout << std::endl;
}
}
You're using a compiler extension that lets you declare arrays with a size determined at runtime.
There is no way to pass a 2D array with such dimensions to a function, since all but one dimension for an array as a function parameter must be known at compile time.
You can use fixed dimensions and use the values read as limits that you pass to the function:
const int max_queries = 100;
const int max_attributes = 100;
void showAttributeUsage(int array[max_queries][max_attributes], int queries, int attributes);
int main()
{
int attVal[max_queries][max_attributes];
int qN = 0;
int aN = 0;
cout << "Enter Number of Queries (<= 100) : ";
cin >> qN;
cout << "\nEnter Number of Attributes (<= 100) : ";
cin >> aN;
cout << "\nEnter Attribute Usage Values" << endl;
for (int n = 0; n < qN; n++)
{
cout << "\n\n***************** COLUMN " << n + 1 <<" *******************\n\n";
for (int i = 0; i < aN; i++)
{
bool bad_input = true;
while (bad_input)
{
bad_input = false; // Assume that input will be correct this time.
cout << "Use(Q" << n + 1 << " , " << "A" << i + 1 << ") = ";
cin >> attVal[n][i];
cout << endl;
if (attVal[n][i] > 1 || attVal[n][i] < 0)
{
cout << "\n\nTHE VALUE MUST BE 1 or 0 . Please Re-Enter The Values\n\n";
bad_input = true;
}
}
}
}
cout << "\n\nYOUR ATTRIBUTE USAGE MATRIX IS\n\n";
showAttributeUsage(attVal, qN, aN);
getch();
return 0;
}
void showAttributeUsage(int att[max_queries][max_attributes], int queries, int attributes)
{
for (int i = 0; i < queries; i++)
{
for (int j = 0; j < attributes; j++)
{
cout << att[i][j] << " ";
}
cout << endl;
}
}
For comparison, the same program using std::vector, which is almost identical but with no size limitations:
void showAttributeUsage(vector<vector<int> > att);
int main()
{
cout << "Enter Number of Queries (<= 100) : ";
cin >> qN;
cout << "\nEnter Number of Attributes (<= 100) : ";
cin >> aN;
vector<vector<int> > attVal(qN, vector<int>(aN));
cout << "\nEnter Attribute Usage Values"<<endl;
for (int n = 0; n < qN; n++)
{
cout<<"\n\n***************** COLUMN "<<n+1<<" *******************\n\n";
for (int i = 0; i < aN; i++)
{
bool bad = true;
while (bad)
{
bad = false;
cout << "Use(Q" << n + 1 << " , " << "A" << i + 1 << ") = ";
cin >> attVal[n][i];
cout << endl;
if (attVal[n][i] > 1 || attVal[n][i] < 0)
{
cout << "\n\nTHE VALUE MUST BE 1 or 0 . Please Re-Enter The Values\n\n";
bad = true;
}
}
}
}
cout << "\n\nYOUR ATTRIBUTE USAGE MATRIX IS\n\n";
showAttributeUsage(attVal);
getch();
return 0;
}
void showAttributeUsage(vector<vector<int> > att);
{
for (int i = 0; i < att.size(); i++)
{
for (int j = 0; j < att[i].size(); j++)
{
cout << att[i][j] << " ";
}
cout << endl;
}
}
The Particular Logic worked for me. At last found it. :-)
int** create2dArray(int rows, int cols) {
int** array = new int*[rows];
for (int row=0; row<rows; row++) {
array[row] = new int[cols];
}
return array;
}
void delete2dArray(int **ar, int rows, int cols) {
for (int row=0; row<rows; row++) {
delete [] ar[row];
}
delete [] ar;
}
void loadDefault(int **ar, int rows, int cols) {
int a = 0;
for (int row=0; row<rows; row++) {
for (int col=0; col<cols; col++) {
ar[row][col] = a++;
}
}
}
void print(int **ar, int rows, int cols) {
for (int row=0; row<rows; row++) {
for (int col=0; col<cols; col++) {
cout << " | " << ar[row][col];
}
cout << " | " << endl;
}
}
int main () {
int rows = 0;
int cols = 0;
cout<<"ENTER NUMBER OF ROWS:\t";cin>>rows;
cout<<"\nENTER NUMBER OF COLUMNS:\t";cin>>cols;
cout<<"\n\n";
int** a = create2dArray(rows, cols);
loadDefault(a, rows, cols);
print(a, rows, cols);
delete2dArray(a, rows, cols);
getch();
return 0;
}
if its c++ then you can use a templete that would work with any number of dimensions
template<typename T>
void func(T& v)
{
// code here
}
int main()
{
int arr[][7] = {
{1,2,3,4,5,6,7},
{1,2,3,4,5,6,7}
};
func(arr);
char triplestring[][2][5] = {
{
"str1",
"str2"
},
{
"str3",
"str4"
}
};
func(triplestring);
return 0;
}