Learn how to a build a cloud-first strategyRegister Now

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

passing back an char[][]??

Ok till I get to out main database I was writing a quick hack.  Anyhow what I have is a DB class to returns some basic things.  One thing I wanted to get back is an and array of char*.  

So in the DB class I have a struct { ... char x[5][50] }

somehow I want to pass back a pointer to this.  I tried char** tried void*. gave up on that.  then I tried using char** and some combination of new char*[5] then new char[50] couldn't seem to get it to allocate.  How can I do any of this?

In otherwords I want to pass back a list of strings.  I don't care how.  I know I shouldn't be passing a pointer back, but the class will be going away soon.
0
micah
Asked:
micah
  • 6
  • 4
  • 2
  • +1
1 Solution
 
ecwCommented:
make a typedef to an [5][50] array of chars, and get you func to return a pointer to this type ie.:

typedef char x_t[5][50];

x_t *func(DB &d)
{
return &d.x;
}
0
 
nietodCommented:
ecw's answer is right according to what you requested.  However, waht you asked for might not be what you want.  In many cases and array of strings is best implimented using an array of character pointers, that is, by using "char * []".  Wethor or not that is better depends on what you are trying to do. If you supply more details as to the nature of the data and the way in which it will be used, I might be able to ofter some suggestions.  In any case, ecw has provided a solution that will work.
0
 
ecwCommented:
Yeah but if you store a char[][] in a class, you know that's what you get with every instance of the class- no further memory allocs needed.  My preference is to store things as char*[], or char**, because I hate boundaries, but it is not always appropriate, or always worth the effort.
In this case,  the class is "going away soon", so changing the storage layout isn't worth the effort.
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.

 
micahAuthor Commented:
char*[] ? not sure I understand you there.  Here is my code


what does it take to pass back _nextHigher?  Once it is passed back how do I print out each element. When I pass it back now it seems to get stomped.  






#ifndef __DB
#define __DB

#include "Device.h"
//
// a realy crappy database
//

struct dbStruct{
  char        _name[50];
  DEVICETYPE  _deviceType;
  char **     _nextHigher;
  int         _nextHigherCount;
  char        _tool[50];

};

class DB{
 public:
  DB();
  ~DB();
  DEVICETYPE getDeviceType(char* name);

  int getNextHigher(char* name,char** data);

  char* getTool(char* name);

 private:
  int findName(char* name);
  dbStruct _data[30];
  int _size;
};
#endif

#include "DB.h"
#include <string.h>

DB::DB(){

  for(int i=0;i<30;i++){
    _data[i]._nextHigher = new char*[5];      
    for(int j=0;j<5;j++)
      _data[i]._nextHigher[j]=new char[50];
  }      
  strcpy(_data[0]._name,"panel");      
  _data[0]._deviceType = PANEL;
  strcpy(_data[0]._nextHigher[0],"fastener_p");
  _data[0]._nextHigherCount=1;
  strcpy(_data[0]._tool,"NULL");

  strcpy(_data[1]._name,"ratchet");                  
  _data[1]._deviceType = ROTATIONAL_TOOL;
  strcpy(_data[1]._nextHigher[0],"NULL");
  _data[1]._nextHigherCount=0;
  strcpy(_data[1]._tool,"NULL");

  strcpy(_data[2]._name,"fastener_p");                  
  _data[2]._deviceType = FASTENER;
  strcpy(_data[2]._nextHigher[0],"NULL");
  _data[2]._nextHigherCount=0;      
  strcpy(_data[2]._tool,"ratchet");

  strcpy(_data[3]._name,"LRU");                  
  _data[3]._deviceType = GENERIC;
  strcpy(_data[3]._nextHigher[0],"fastener_p");
  strcpy(_data[3]._nextHigher[1],"harness_p");
  _data[3]._nextHigherCount=2;      
  strcpy(_data[3]._tool,"NULL");

  strcpy(_data[4]._name,"harness_p");                  
  _data[4]._deviceType = HARNESS;
  strcpy(_data[4]._nextHigher[0],"NULL");
  _data[4]._nextHigherCount=0;      
  strcpy(_data[4]._tool,"NULL");  
 
 _size = 5;
}


DB::~DB(){
  for(int i=0;i<30;i++){
    for(int j=0;j<5;j++)
      delete [] _data[i]._nextHigher[j];
    delete [] _data[i]._nextHigher;
  }      
}

DEVICETYPE        DB::getDeviceType(char* name){
  int i=findName(name);
  if( i >=0 )
      return _data[i]._deviceType;
    return INVALID;
 
}
 

int             DB::getNextHigher(char* name,char** data)
{
  int i=findName(name);
  if(i >=0 ){
    data = &_data[i]._nextHigher;
    return _data[i]._nextHigherCount;
  }
  else
    return 0;
}

char*             DB::getTool(char* name){
  int i=findName(name);      
  if(i >=0 )
    return _data[i]._tool;
  else
    return NULL;
}
//
/** PRIVATE **/
//
int            DB::findName(char* name){
  for(int i=0;i<_size;i++){
    if(!strcmp(_data[i]._name,name))
      return i;
  }
  return -1;
}


0
 
micahAuthor Commented:
char*[] ? not sure I understand you there.  Here is my code


what does it take to pass back _nextHigher?  Once it is passed back how do I print out each element. When I pass it back now it seems to get stomped.  






#ifndef __DB
#define __DB

#include "Device.h"
//
// a realy crappy database
//

struct dbStruct{
  char        _name[50];
  DEVICETYPE  _deviceType;
  char **     _nextHigher;
  int         _nextHigherCount;
  char        _tool[50];

};

class DB{
 public:
  DB();
  ~DB();
  DEVICETYPE getDeviceType(char* name);

  int getNextHigher(char* name,char** data);

  char* getTool(char* name);

 private:
  int findName(char* name);
  dbStruct _data[30];
  int _size;
};
#endif

#include "DB.h"
#include <string.h>

DB::DB(){

  for(int i=0;i<30;i++){
    _data[i]._nextHigher = new char*[5];      
    for(int j=0;j<5;j++)
      _data[i]._nextHigher[j]=new char[50];
  }      
  strcpy(_data[0]._name,"panel");      
  _data[0]._deviceType = PANEL;
  strcpy(_data[0]._nextHigher[0],"fastener_p");
  _data[0]._nextHigherCount=1;
  strcpy(_data[0]._tool,"NULL");

  strcpy(_data[1]._name,"ratchet");                  
  _data[1]._deviceType = ROTATIONAL_TOOL;
  strcpy(_data[1]._nextHigher[0],"NULL");
  _data[1]._nextHigherCount=0;
  strcpy(_data[1]._tool,"NULL");

  strcpy(_data[2]._name,"fastener_p");                  
  _data[2]._deviceType = FASTENER;
  strcpy(_data[2]._nextHigher[0],"NULL");
  _data[2]._nextHigherCount=0;      
  strcpy(_data[2]._tool,"ratchet");

  strcpy(_data[3]._name,"LRU");                  
  _data[3]._deviceType = GENERIC;
  strcpy(_data[3]._nextHigher[0],"fastener_p");
  strcpy(_data[3]._nextHigher[1],"harness_p");
  _data[3]._nextHigherCount=2;      
  strcpy(_data[3]._tool,"NULL");

  strcpy(_data[4]._name,"harness_p");                  
  _data[4]._deviceType = HARNESS;
  strcpy(_data[4]._nextHigher[0],"NULL");
  _data[4]._nextHigherCount=0;      
  strcpy(_data[4]._tool,"NULL");  
 
 _size = 5;
}


DB::~DB(){
  for(int i=0;i<30;i++){
    for(int j=0;j<5;j++)
      delete [] _data[i]._nextHigher[j];
    delete [] _data[i]._nextHigher;
  }      
}

DEVICETYPE        DB::getDeviceType(char* name){
  int i=findName(name);
  if( i >=0 )
      return _data[i]._deviceType;
    return INVALID;
 
}
 

int             DB::getNextHigher(char* name,char** data)
{
  int i=findName(name);
  if(i >=0 ){
    data = &_data[i]._nextHigher;
    return _data[i]._nextHigherCount;
  }
  else
    return 0;
}

char*             DB::getTool(char* name){
  int i=findName(name);      
  if(i >=0 )
    return _data[i]._tool;
  else
    return NULL;
}
//
/** PRIVATE **/
//
int            DB::findName(char* name){
  for(int i=0;i<_size;i++){
    if(!strcmp(_data[i]._name,name))
      return i;
  }
  return -1;
}


0
 
nietodCommented:
Change GetNextHigher to to take a "char ** &"  That i, it takes a parameter that it can alter (that is what the & is for) and that parameter is a pointer to a pointer to characters.

int DB::getNextHigher(char* name,char** &data)
      {
        int i=findName(name);
        if(i >=0 ){
          data = _data[i]._nextHigher;
          return _data[i]._nextHigherCount;
        }
        else
          return 0;
      }
0
 
nietodCommented:
I don't see a place where you are using this procedure, so I'll make one up.

char **StrAry;
int StrCnt = SomeDB.getNextHigher("Searchforme",StrAry);

for (int i = 0; i < StrCnt; ++i)
   cout << *StrAry++;

let me know if you have any questions.  I have not answered because ecw was here first and I believe could have provided the same information.

FYI   you may want to add the "const" declaration to your char * parameters that are treated as constant, for example, the first parameter to getNextHigher.
0
 
micahAuthor Commented:
This is how I want to call getNextHigher, what do I need to do to have junk point to the contents of _nextHigher in the struct in DB.

How do I get the following to work

#include "DB.h"
#include "iostream.h"
void main(){
  DB db;
  char** junk;
  int junkCount;
  junkCount=db.getNextHigher("panel",&junk);
  cout<<junk[0]<<endl;
}
0
 
nietodCommented:
That is exactly what I showed, you except I passed the parameter (junk) by reference so an  wasn't needed, that is my way you specify

 junkCount=db.getNextHigher("panel",junk);  // no &

instead of

 junkCount=db.getNextHigher("panel",&junk); // with &

If you want the &, then the GetNextHigher function should take a pointer to a char **, rather than a reference to a char **.  That is it should take "char ***", rather thann "char ** &"  In that case it would be

int DB::getNextHigher(char* name,char*** data)
{
        int i=findName(name);
        if(i >=0 ){
             data = &_data[i]._nextHigher;
             return _data[i]._nextHigherCount;
         }
         else
                return 0;
 }


0
 
Answers2000Commented:
Maybe this is way out in left field,

 but why not pass back either a point to the structure or an array/vector of strings (or reference/pointer to one)


0
 
Answers2000Commented:
Maybe this is way out in left field,

 but why not pass back either a point to the structure or an array/vector of strings (or reference/pointer to one)


0
 
nietodCommented:
Don't you think the question was already answered?  I choose not to answer because ecw really deserved it, he was here first and suplied the correct answer.  I oftered additional help if additional information was supplied and gave it.  
0
 
micahAuthor Commented:
The comments where very good, the final proposed answer which came after the comments was a 'C'
0
 
nietodCommented:
micah, you can choose who gets the grade.  In the future, if you don't like the submitted answer, you can reject it and ask another expert to submit a "dummy" answer.  Keeping the system fair will help to keep it running.  I know of at least two experts who left (and whose contributions are sorely lost) because other experts were "stealing" their points.
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 6
  • 4
  • 2
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now