0

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++;
    }
}
Jarod42
  • 173,454
  • 13
  • 146
  • 250
Faisal Naseer
  • 3,559
  • 31
  • 48

7 Answers7

1

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);
Jarod42
  • 173,454
  • 13
  • 146
  • 250
1

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.

PaulMcKenzie
  • 31,493
  • 4
  • 19
  • 38
0

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.

lakesh
  • 25,623
  • 57
  • 163
  • 254
0

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;
    }
}
Community
  • 1
  • 1
bp4D
  • 819
  • 10
  • 19
0

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;
    }
}    
molbdnilo
  • 55,783
  • 3
  • 31
  • 71
  • BTW, in the first case, it should be `void showAttributeUsage(int (&att)[max_queries][max_attributes], int queries, int attributes) ` – Jarod42 May 27 '14 at 17:07
  • @Jarod42 Yeah, if you want safety. I hesitate to throw the stranger syntactic incantations of the language at beginners. – molbdnilo May 27 '14 at 17:35
0

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;

}
Faisal Naseer
  • 3,559
  • 31
  • 48
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;
}