passing dynamic 2-dimensional array to function

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • bushnellweb
    New Member
    • Jan 2010
    • 48

    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?

    Code:
    #include <iostream>
    #include <string>
    #include <fstream>
    #include <new>
    #include <iomanip>
    
    using namespace std;
    
    
    /*
    	function: countRecords
    	params: string fileName, bool outputTF
    	purpose: counts records from passed file name and outputs data if bool is true
    */
    int countRecords(string fileName, bool outputTF)
    {
    	ifstream inFile;
    	int recordCount = 0;
    
    	inFile.open(fileName.c_str(),ios::in);
    	if(inFile.is_open())
    	{
    		//priming read
    		inFile.ignore(1000,'\n');
    		recordCount = 1;
    
    		//loop
    		while(!inFile.eof())
    		{
    			inFile.ignore(1000,'\n');
    			recordCount++;
    		}
    
    		if(outputTF == true)
    		{
    			cout << "recordCount= " << recordCount << endl;
    		}
    		
    	}else{ cout << "File would not open!" << endl; }
    	inFile.close();
    
    	return recordCount;
    }
    
    void listData(string arr)
    {
    	cout.setf(ios::left);
    	cout << setw(5) << "#" << setw(5) << "ID" << setw(50) << "DESC" << setw(8) << "COST" << setw(6) << "SUPPLY" << endl;
    	cout << endl;
    
    }
    
    void changeData(string arr)
    {
    	listData(arr);
    	system("pause");
    }
    
    int printMenu()
    {
    	
    	int option = 0;
    	cout << endl;
    	cout << " 1  Change Data" << endl;
    	cout << " 0  Exit" << endl;
    
    	cout << "Type number from left to choose operation: ";
    	cin >> option;
    
    	return option;
    }
    
    // ***************** MAIN PROCEDURE ***********************
    int main()
    {
    	
    	string fileName = "data1.dat";
    	int c = countRecords(fileName,false);//one hundred million records MAX
    
    	string **p = new string * [c];
    	for(int i=0; i<c; i++)
    	{
    		p[i] = new string [4];
    	}
    		
    	ifstream inFile;
    	inFile.open("data1.dat",ios::in);
    	if(inFile.is_open())
    	{
    		while(!inFile.eof())
    		{
    			for(int i=0; i<c; i++)
    			{
    				for(int t=0; t<4; t++)
    				{
    					if(t==3)
    					{
    						getline(inFile,p[i][t],'\n');
    						//cout << t << ": " << p[i][t] << endl;
    						//system("pause");
    					}else{
    						getline(inFile,p[i][t],'_');
    						//cout << t << ": " << p[i][t] << endl;
    						//system("pause");
    					}
    				}//end for t
    			}//end for i
    		}//end while !eof
    		
    		int option = printMenu();
    		while(option != 0)
    		{
    			system("cls");
    
    			if(option == 1){ changeData(p); } 
    			else if(option == 2){ /*function here*/ }
    
    			option = printMenu();
    		}
    	}else{
    		cout << "File '" << fileName << "' did not open!" << endl;
    		system("pause");
    		system("exit");
    	}//end if is_open
    
    // Memory Cleanup - p
    for (int i = 0; i < c; i++)
    {
    	delete[] p[i];
    }
    delete[] p;
    p = 0;
    
    	
    
    
    
    
    //return 0
    return 0;
    }
  • RedSon
    Recognized Expert Expert
    • Jan 2007
    • 4980

    #2
    Are you going to need to pass that by value or by reference?

    Comment

    • Banfa
      Recognized Expert Expert
      • Feb 2006
      • 9067

      #3
      Read This

      Comment

      • RedSon
        Recognized Expert Expert
        • Jan 2007
        • 4980

        #4
        suryakantb,

        Your response was totally off topic and has been deleted.

        Comment

        • bushnellweb
          New Member
          • Jan 2010
          • 48

          #5
          I WILL need to change the data

          Comment

          • bushnellweb
            New Member
            • Jan 2010
            • 48

            #6
            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?);

            Comment

            • RedSon
              Recognized Expert Expert
              • Jan 2007
              • 4980

              #7
              Did you read the article Banfa posted. Especially the section about "Passing Multi-dimensional Arrays to Functions"

              Comment

              • bushnellweb
                New Member
                • Jan 2010
                • 48

                #8
                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.

                Comment

                • Banfa
                  Recognized Expert Expert
                  • Feb 2006
                  • 9067

                  #9
                  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:st ring 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:st ring (*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.

                  Code:
                  #include <iostream>
                  #include <string>
                  #include <vector>
                  
                  using namespace std;
                  
                  const int SOME_MEANINGFUL_NAME = 4;
                  
                  // The C++ Way
                  void func1(vector<vector<string> >& vec)
                  {
                      vector<vector<string> >::iterator outer;
                  
                      for(outer = vec.begin(); outer != vec.end(); outer++)
                      {
                          vector<string>::iterator inter;
                  
                          for(inter = outer->begin(); inter != outer->end(); inter++)
                          {
                              cout << *inter << endl;
                          }
                      }
                  }
                  
                  // The C Way
                  void func2(vector<vector<string> >& vec)
                  {
                      vector<vector<string> >::size_type outer;
                  
                      for(outer = 0; outer < vec.size(); outer++)
                      {
                          vector<string>::size_type inter;
                  
                          for(inter = 0; inter < vec[outer].size(); inter++)
                          {
                              cout << vec[outer][inter] << endl;
                          }
                      }
                  }
                  
                  int main()
                  {
                      string fileName = "data1.dat";
                      int c = 20; //countRecords(fileName,false);//one hundred million records MAX
                  
                      vector<vector<string> > vec;
                  
                      vector<string> initialiser; // Something we can use to initialise our main vector
                  
                      initialiser.resize(SOME_MEANINGFUL_NAME);
                  
                      vec.resize(c, initialiser);
                  
                      func1(vec);
                      func2(vec);
                  }

                  Comment

                  • bushnellweb
                    New Member
                    • Jan 2010
                    • 48

                    #10
                    Error 1 error C2664: 'changeData' : cannot convert parameter 1 from 'std::string **' to 'std::string (*)[4]' c:\users\nick\d ocuments\visual studio 2005\projects\n rsproject_001\n rsproject_001\m ain.cpp 117

                    Thats the error I get when doing this:

                    Code:
                    void changeData(string (*arr)[4])
                    {
                         // why even bother getting a c++ job
                         system("pause");
                    }
                    
                    int main()
                    {
                    
                         int c = countRecords(fileName,false);//one hundred million records MAX
                    
                         string **p = new string * [c];
                         for(int i=0; i<c; i++)
                         {
                              p[i] = new string [4];
                         }
                    
                         changeData(p);

                    Comment

                    • Banfa
                      Recognized Expert Expert
                      • Feb 2006
                      • 9067

                      #11
                      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.

                      Comment

                      • bushnellweb
                        New Member
                        • Jan 2010
                        • 48

                        #12
                        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

                        Comment

                        Working...