Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 251
  • Last Modified:

Create Multidimensional Dynamic Array Pointer

I have an array pointer that I need to be able to erase and reload new data.  Currently, I have global array constant that I am using:

char *MENUARRAY[19][17] = {{{"0"},"BeginMenu","","1","","1","","1","","1","","1","","1","","1","NULL"}
,{"1","SelectProgram.htm","Rotate","NULL","Vacuum","NULL","Setup","2","Select Program","18","Shutdown System","CallSystemShutdown","NULL","NULL","NULL","NULL"}
,{"2","Password.htm","Exit Setup","1","Enter","3","Undo","3","1","NULL","2","NULL","3","NULL","4","NULL"}
...etc.

I need to load the base table in and then append a dynamic number of elements so that this array can be used for a menu program.  How do I do this?  Do I use alloc and malloc?  I am very confused.

Don't hurt me because I'm a newbie programmer.

=)
0
vivekpara
Asked:
vivekpara
3 Solutions
 
OnegaZhangCommented:
use stl container such as std::deque<std::string>
0
 
deltacaddCommented:
The best method according to me would be to use linked lists to load menu items. From your example, I assume that the number of menus horizontally are variable and also the number of vertical menu items in each menu is also variable. Do you have an externally defined menu resource (say as a text file)? If that is the case, a simple unidirectional linked list would suffice.
0
 
SkonenCommented:
I'm definately with OnegaZhang on this one, using STL's vector or deque class/template is the way to go. It can be done without using STL, and yes using malloc and realloc, or new and delete, are the typical methods of going about it, but I certainly wouldn't recommend it when STL provides a class for such tasks.

It's late, so I didn't have an opportunity to find you some great tutorials. But the following may help you out:

An "overview" of STL: http://cplus.about.com/library/weekly/aa101003e.htm
MSDN Documentation: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcstdlib/html/vclrfvectorclass.asp
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
vivekparaAuthor Commented:
The vertical number is dynamic...the horizontal are a static list of values for all controls.  I was going to change it from being hard coded to being in some comma delimited file.

The dynamic part is added to the bottom and created after parsing through directories.  Basically, I'm adding more "levels" to the controls.  For all intents and purposes, I just want to be able to add items and need to basically clear and load when new "levels" are added.

I'll check that stuff out and see if I can figure it out.

If anyone has any examples, it would be appreciated.

=)
0
 
vivekparaAuthor Commented:
I've tried a number of times to use vector.  I see that there are ways to use the equals operator if you override the class, and I'm trying to make it a two dimensional array.  I used this matrix helper class to try and do it:

    #ifndef MATRIX_H
    #define MATRIX_H

    #include <vector>  //STL-klasse
    #include <assert.h> //erstatter assert.h

          using std::vector;

    //-------------- class row for Matrix: -------------------

    template <class T>
    class row
    {
    public:            
     //klassen indeholder netop én vector = 1 række i Matrix:
     vector<T> aRow;
    };


    //-------------------- class Matrix --------------------------------
    template <class T>
    class Matrix
    {
    public:
     Matrix  (size_t Rows=0, size_t Cols=0);
     Matrix  (size_t Rows, size_t Cols, const T& Value);  
     Matrix  (const Matrix<T>& source);       //copy-constructor
     virtual ~Matrix() {};

     void Init(const T& Value);

     vector<T>& operator[] (size_t index);       //LValue indexering
     const vector<T>& operator[] (size_t index) const; //RValue indexering
     const T& GetAt (size_t Row, size_t Col) const;
     void  SetAt (size_t Row, size_t Col, const T& Value);

     Matrix<T>& operator= (const Matrix<T>& m); //assignment

     virtual void Resize(size_t Rows, size_t Cols);  
     virtual void Resize(size_t Rows, size_t Cols, const T& Value);  

     //inspektører:
     size_t NoOfRows () const;
     size_t NoOfCols () const;

    protected:

     vector< row<T> > rows;
    }; //end of class Matrix

 


   
   template <class T>
   Matrix<T>::Matrix (size_t Rows, size_t Cols)
                      : rows(Rows)
   {
     for (size_t i = 0; i < Rows; i++)
           rows[i].aRow.resize(Cols);
   }
 
   template <class T>
   Matrix<T>::Matrix  (size_t Rows, size_t Cols, const T& Value)
          : rows(Rows)
   {
         for (size_t i = 0; i < Rows; i++)
           rows[i].aRow.resize(Cols, Value);
   }

   template <class T>
   Matrix<T>::Matrix  (const Matrix<T>& source)
          : rows(source.NoOfRows() )
   {
        for (size_t i = 0; i < source.NoOfRows(); i++)
        {
          rows[i].aRow = source.rows[i].aRow;   //vector assignment
        }
   }
   
   template <class T>
   void Matrix<T>::Init  (const T& Value)
   {
     size_t i, j;
     for (i=0; i < NoOfRows(); ++i)
       for (j=0; j < NoOfCols(); ++j)
         rows[i].aRow[j] = Value;
   }

   template <class T>
   vector<T>& Matrix<T>::operator[] (size_t index)  //LValue
   {
     assert (0 <= index && index < NoOfRows());
     return rows[index].aRow;
     //aRow er en vector<T>
     //Ved indexering med [i][j] på en matrix, vil [i]
     //returnere vector<T> i den i'te række.
     //På denne bruges [j], således at det j'te element i den i'te række returneres.
     //Og det er netop element [i][j] i matrix'en!
   }

   template <class T>
   const vector<T>& Matrix<T>::operator[] (size_t index) const //RValue
   {
     assert (index < NoOfRows());
     return rows[index].aRow;
   }

   template <class T>
   const T& Matrix<T>::GetAt (size_t Row, size_t Col) const
   {
     return rows[Row].aRow[Col];
   }

   template <class T>
   void Matrix<T>::SetAt (size_t Row, size_t Col, const T& Value)
   {
     rows[Row].aRow[Col] = Value;
   }
   
   template <class T>
   Matrix<T>& Matrix<T>::operator= (const Matrix<T>& m)
   {
     if (this != &m) //check for selv-assignment
     {
       rows.resize(m.NoOfRows()); //frigiv eller alloker memory

       //kopier rækkerne fra m, en række ad gangen:
          for (size_t i = 0; i < m.NoOfRows(); ++i)
         rows[i].aRow = m.rows[i].aRow; //vector assignment
     }
     return *this;
   }
   
   template <class T>
   void Matrix<T>::Resize(size_t Rows, size_t Cols)
   {
     rows.resize(Rows);
     for (size_t i=0; i < Rows; ++i)
       rows[i].aRow.resize(Cols);
   }

   template <class T>
   void Matrix<T>::Resize(size_t Rows, size_t Cols, const T& Value)  
   {
     rows.resize(Rows);
     for (size_t i=0; i < Rows; ++i)
       rows[i].aRow.resize(Cols, Value);
   }

   template <class T>
   size_t Matrix<T>::NoOfRows () const
   {
     return rows.size();
   }

   template <class T>
   size_t Matrix<T>::NoOfCols () const
   {
     return rows[0].aRow.size();
   }

  #endif
0
 
vivekparaAuthor Commented:
I put this in my actual Dialog based application part (with an include for the matrix.h header I had created).

typedef  struct dynmenuarray
{
      CString  str1;
      CString  str2;
        CString  str3;
        CString  str4;
        CString  str5;
        CString  str6;
        CString  str7;
        CString  str8;
        CString  str9;
        CString  str10;
        CString  str11;
        CString  str12;
        CString  str13;
        CString  str14;
        CString  str15;
        CString  str16;
        CString  str17;
}MyStruct;

Matrix(size_t Rows/* =0 */, size_t Cols/* =0 */);

I keep getting this:

C:\UI Code and Executable\UIMFCNew\UIMFC\UIMFCDlg.cpp(148) : error C2955: 'Matrix' : use of class template requires template argument list
        c:\ui code and executable\uimfcnew\uimfc\matrix.h(49) : see declaration of 'Matrix'

Eventually, I want to be able to fill the vector something like this:

for (a = 0; a < 20; a++)
{
     for (b = 0; b < 20; b++)
     {
            CString tempstring;
            tempstring = MENUARRAY[a][b]
            dynmenuarray[a][b] =  tempstring;
     }
}

And then be able to fill the variable members like this:

LButton1 = MENUARRAY[currlevel][2];
LButton2 = MENUARRAY[currlevel][4];

What am I doing wrong?  Thanks for any help.
0
 
vivekparaAuthor Commented:
You guys led me in the right direction.  I solved it using STL vector.  Works just like an array if you use can set up the template correctly.  Axter gave me a template that was perfect!

Back to klugy coding...thanks again!

=)
0

Featured Post

[Webinar] Cloud and Mobile-First Strategy

Maybe you’ve fully adopted the cloud since the beginning. Or maybe you started with on-prem resources but are pursuing a “cloud and mobile first” strategy. Getting to that end state has its challenges. Discover how to build out a 100% cloud and mobile IT strategy in this webinar.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now