469,341 Members | 7,542 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,341 developers. It's quick & easy.

passing dynamic 2-dimensional array to function

All I want to do is pass my array "p" which is a 2-dimensional string array to the function changeData().... Can't remember how to pass that. Any ideas?

Expand|Select|Wrap|Line Numbers
  1. #include <iostream>
  2. #include <string>
  3. #include <fstream>
  4. #include <new>
  5. #include <iomanip>
  6.  
  7. using namespace std;
  8.  
  9.  
  10. /*
  11.     function: countRecords
  12.     params: string fileName, bool outputTF
  13.     purpose: counts records from passed file name and outputs data if bool is true
  14. */
  15. int countRecords(string fileName, bool outputTF)
  16. {
  17.     ifstream inFile;
  18.     int recordCount = 0;
  19.  
  20.     inFile.open(fileName.c_str(),ios::in);
  21.     if(inFile.is_open())
  22.     {
  23.         //priming read
  24.         inFile.ignore(1000,'\n');
  25.         recordCount = 1;
  26.  
  27.         //loop
  28.         while(!inFile.eof())
  29.         {
  30.             inFile.ignore(1000,'\n');
  31.             recordCount++;
  32.         }
  33.  
  34.         if(outputTF == true)
  35.         {
  36.             cout << "recordCount= " << recordCount << endl;
  37.         }
  38.  
  39.     }else{ cout << "File would not open!" << endl; }
  40.     inFile.close();
  41.  
  42.     return recordCount;
  43. }
  44.  
  45. void listData(string arr)
  46. {
  47.     cout.setf(ios::left);
  48.     cout << setw(5) << "#" << setw(5) << "ID" << setw(50) << "DESC" << setw(8) << "COST" << setw(6) << "SUPPLY" << endl;
  49.     cout << endl;
  50.  
  51. }
  52.  
  53. void changeData(string arr)
  54. {
  55.     listData(arr);
  56.     system("pause");
  57. }
  58.  
  59. int printMenu()
  60. {
  61.  
  62.     int option = 0;
  63.     cout << endl;
  64.     cout << " 1  Change Data" << endl;
  65.     cout << " 0  Exit" << endl;
  66.  
  67.     cout << "Type number from left to choose operation: ";
  68.     cin >> option;
  69.  
  70.     return option;
  71. }
  72.  
  73. // ***************** MAIN PROCEDURE ***********************
  74. int main()
  75. {
  76.  
  77.     string fileName = "data1.dat";
  78.     int c = countRecords(fileName,false);//one hundred million records MAX
  79.  
  80.     string **p = new string * [c];
  81.     for(int i=0; i<c; i++)
  82.     {
  83.         p[i] = new string [4];
  84.     }
  85.  
  86.     ifstream inFile;
  87.     inFile.open("data1.dat",ios::in);
  88.     if(inFile.is_open())
  89.     {
  90.         while(!inFile.eof())
  91.         {
  92.             for(int i=0; i<c; i++)
  93.             {
  94.                 for(int t=0; t<4; t++)
  95.                 {
  96.                     if(t==3)
  97.                     {
  98.                         getline(inFile,p[i][t],'\n');
  99.                         //cout << t << ": " << p[i][t] << endl;
  100.                         //system("pause");
  101.                     }else{
  102.                         getline(inFile,p[i][t],'_');
  103.                         //cout << t << ": " << p[i][t] << endl;
  104.                         //system("pause");
  105.                     }
  106.                 }//end for t
  107.             }//end for i
  108.         }//end while !eof
  109.  
  110.         int option = printMenu();
  111.         while(option != 0)
  112.         {
  113.             system("cls");
  114.  
  115.             if(option == 1){ changeData(p); } 
  116.             else if(option == 2){ /*function here*/ }
  117.  
  118.             option = printMenu();
  119.         }
  120.     }else{
  121.         cout << "File '" << fileName << "' did not open!" << endl;
  122.         system("pause");
  123.         system("exit");
  124.     }//end if is_open
  125.  
  126. // Memory Cleanup - p
  127. for (int i = 0; i < c; i++)
  128. {
  129.     delete[] p[i];
  130. }
  131. delete[] p;
  132. p = 0;
  133.  
  134.  
  135.  
  136.  
  137.  
  138.  
  139. //return 0
  140. return 0;
  141. }
  142.  
Jan 28 '10 #1

✓ answered by Banfa

You appear to be using a variable sized array of array size 4 of strings.

std:string array[N][4];

To pass that to a function you have a number of options, these are limited by the fact tat N is variable but the fact that 4 is not simplifies things a bit. To start with since we will be using 4 a lot we should define a constant with its semantic meaning, that way we can use the constant in our code and should it need to change we only have to change 1 place. I believe the type of array indexes is int so declare

const int SOME_MEANINGFUL_NAME = 4;

Since this is constant we can included it has part of the type passed to the function rather than pass the size of the second dimension as a parameter so for the first parameter of our function what we will do is write our array type leaving out the dimensions we don't know and passing a size parameter for each of the unknown dimensions

void function(std:string pointer[][SOME_MEANINGFUL_NAME], int size);

And actually that is it because in a function parameter list the left most set of [] is allowed to be empty. it declares a pointer to type, this is its equivalent to

void function(std:string (*pointer)[SOME_MEANINGFUL_NAME], int size);

Note the parenthesis are required in this syntax otherwise you declare an array of pointers rather than a pointer to an array.

It gets a little more complex if you have 2 or more unknown array dimensions.


However since you are using string you must be using C++ and if you are using C++ you should be using vectors not arrays. They handle all the memory management for you and generally make things easier.

Expand|Select|Wrap|Line Numbers
  1. #include <iostream>
  2. #include <string>
  3. #include <vector>
  4.  
  5. using namespace std;
  6.  
  7. const int SOME_MEANINGFUL_NAME = 4;
  8.  
  9. // The C++ Way
  10. void func1(vector<vector<string> >& vec)
  11. {
  12.     vector<vector<string> >::iterator outer;
  13.  
  14.     for(outer = vec.begin(); outer != vec.end(); outer++)
  15.     {
  16.         vector<string>::iterator inter;
  17.  
  18.         for(inter = outer->begin(); inter != outer->end(); inter++)
  19.         {
  20.             cout << *inter << endl;
  21.         }
  22.     }
  23. }
  24.  
  25. // The C Way
  26. void func2(vector<vector<string> >& vec)
  27. {
  28.     vector<vector<string> >::size_type outer;
  29.  
  30.     for(outer = 0; outer < vec.size(); outer++)
  31.     {
  32.         vector<string>::size_type inter;
  33.  
  34.         for(inter = 0; inter < vec[outer].size(); inter++)
  35.         {
  36.             cout << vec[outer][inter] << endl;
  37.         }
  38.     }
  39. }
  40.  
  41. int main()
  42. {
  43.     string fileName = "data1.dat";
  44.     int c = 20; //countRecords(fileName,false);//one hundred million records MAX
  45.  
  46.     vector<vector<string> > vec;
  47.  
  48.     vector<string> initialiser; // Something we can use to initialise our main vector
  49.  
  50.     initialiser.resize(SOME_MEANINGFUL_NAME);
  51.  
  52.     vec.resize(c, initialiser);
  53.  
  54.     func1(vec);
  55.     func2(vec);
  56. }
  57.  

11 3603
RedSon
5,000 Expert 4TB
Are you going to need to pass that by value or by reference?
Jan 28 '10 #2
Banfa
9,064 Expert Mod 8TB
Read This
Jan 28 '10 #3
RedSon
5,000 Expert 4TB
suryakantb,

Your response was totally off topic and has been deleted.
Jan 29 '10 #4
I WILL need to change the data
Jan 29 '10 #5
changeData(&p);
if that is how i pass it then what do i write in the function args

void changeData(WTF do i write here to accept the array?);
Jan 29 '10 #6
RedSon
5,000 Expert 4TB
Did you read the article Banfa posted. Especially the section about "Passing Multi-dimensional Arrays to Functions"
Jan 29 '10 #7
yeah and I've tried passing different ways and the problem is that I don't understand WHY to do those things so it doesn't process in my brain HOW to do what I am doing. I have experimented and failed thats why I am asking for help.
Jan 29 '10 #8
Banfa
9,064 Expert Mod 8TB
You appear to be using a variable sized array of array size 4 of strings.

std:string array[N][4];

To pass that to a function you have a number of options, these are limited by the fact tat N is variable but the fact that 4 is not simplifies things a bit. To start with since we will be using 4 a lot we should define a constant with its semantic meaning, that way we can use the constant in our code and should it need to change we only have to change 1 place. I believe the type of array indexes is int so declare

const int SOME_MEANINGFUL_NAME = 4;

Since this is constant we can included it has part of the type passed to the function rather than pass the size of the second dimension as a parameter so for the first parameter of our function what we will do is write our array type leaving out the dimensions we don't know and passing a size parameter for each of the unknown dimensions

void function(std:string pointer[][SOME_MEANINGFUL_NAME], int size);

And actually that is it because in a function parameter list the left most set of [] is allowed to be empty. it declares a pointer to type, this is its equivalent to

void function(std:string (*pointer)[SOME_MEANINGFUL_NAME], int size);

Note the parenthesis are required in this syntax otherwise you declare an array of pointers rather than a pointer to an array.

It gets a little more complex if you have 2 or more unknown array dimensions.


However since you are using string you must be using C++ and if you are using C++ you should be using vectors not arrays. They handle all the memory management for you and generally make things easier.

Expand|Select|Wrap|Line Numbers
  1. #include <iostream>
  2. #include <string>
  3. #include <vector>
  4.  
  5. using namespace std;
  6.  
  7. const int SOME_MEANINGFUL_NAME = 4;
  8.  
  9. // The C++ Way
  10. void func1(vector<vector<string> >& vec)
  11. {
  12.     vector<vector<string> >::iterator outer;
  13.  
  14.     for(outer = vec.begin(); outer != vec.end(); outer++)
  15.     {
  16.         vector<string>::iterator inter;
  17.  
  18.         for(inter = outer->begin(); inter != outer->end(); inter++)
  19.         {
  20.             cout << *inter << endl;
  21.         }
  22.     }
  23. }
  24.  
  25. // The C Way
  26. void func2(vector<vector<string> >& vec)
  27. {
  28.     vector<vector<string> >::size_type outer;
  29.  
  30.     for(outer = 0; outer < vec.size(); outer++)
  31.     {
  32.         vector<string>::size_type inter;
  33.  
  34.         for(inter = 0; inter < vec[outer].size(); inter++)
  35.         {
  36.             cout << vec[outer][inter] << endl;
  37.         }
  38.     }
  39. }
  40.  
  41. int main()
  42. {
  43.     string fileName = "data1.dat";
  44.     int c = 20; //countRecords(fileName,false);//one hundred million records MAX
  45.  
  46.     vector<vector<string> > vec;
  47.  
  48.     vector<string> initialiser; // Something we can use to initialise our main vector
  49.  
  50.     initialiser.resize(SOME_MEANINGFUL_NAME);
  51.  
  52.     vec.resize(c, initialiser);
  53.  
  54.     func1(vec);
  55.     func2(vec);
  56. }
  57.  
Jan 29 '10 #9
Error 1 error C2664: 'changeData' : cannot convert parameter 1 from 'std::string **' to 'std::string (*)[4]' c:\users\nick\documents\visual studio 2005\projects\nrsproject_001\nrsproject_001\main.c pp 117

Thats the error I get when doing this:

Expand|Select|Wrap|Line Numbers
  1.  
  2. void changeData(string (*arr)[4])
  3. {
  4.      // why even bother getting a c++ job
  5.      system("pause");
  6. }
  7.  
  8. int main()
  9. {
  10.  
  11.      int c = countRecords(fileName,false);//one hundred million records MAX
  12.  
  13.      string **p = new string * [c];
  14.      for(int i=0; i<c; i++)
  15.      {
  16.           p[i] = new string [4];
  17.      }
  18.  
  19.      changeData(p);
  20.  
  21.  
  22.  
Jan 31 '10 #10
Banfa
9,064 Expert Mod 8TB
That is because p is not a pointer to an array of 4 string, string(*)[4], it is a pointer to a pointer to a string. Neither is *p. You need to change your declaration of p to a more specific type, to wit a pointer to string[4] like so

string (*p)[SOME_MEANINGFUL_NAME];

You can allocate the entire array with

p = new string [10][SOME_MEANINGFUL_NAME];

You no longer need a loop to allocate all the little sub arrays.
Jan 31 '10 #11
thanks for the help I got it working..just had to read it a few times. How come c++ is so complicated? In any other language a multi-dim array takes 3 minutes to figure out
Feb 3 '10 #12

Post your reply

Sign in to post your reply or Sign up for a free account.

Similar topics

3 posts views Thread by Peter Bailey | last post: by
6 posts views Thread by Scott Zabolotzky | last post: by
4 posts views Thread by spx27 | last post: by
3 posts views Thread by Leo J. Hart IV | last post: by
8 posts views Thread by Sandy Pittendrigh | last post: by
1 post views Thread by CARIGAR | last post: by
reply views Thread by suresh191 | last post: by
1 post views Thread by haryvincent176 | last post: by
1 post views Thread by Marylou17 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.