Solved

passing back an char[][]??

Posted on 1998-08-21
14
229 Views
Last Modified: 2010-08-05
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
Comment
Question by:micah
  • 6
  • 4
  • 2
  • +1
14 Comments
 
LVL 5

Expert Comment

by:ecw
Comment Utility
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
 
LVL 22

Expert Comment

by:nietod
Comment Utility
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
 
LVL 5

Expert Comment

by:ecw
Comment Utility
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
 

Author Comment

by:micah
Comment Utility
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
 

Author Comment

by:micah
Comment Utility
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
 
LVL 22

Expert Comment

by:nietod
Comment Utility
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
 
LVL 22

Expert Comment

by:nietod
Comment Utility
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
Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

 

Author Comment

by:micah
Comment Utility
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
 
LVL 22

Expert Comment

by:nietod
Comment Utility
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
 
LVL 8

Accepted Solution

by:
Answers2000 earned 100 total points
Comment Utility
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
 
LVL 8

Expert Comment

by:Answers2000
Comment Utility
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
 
LVL 22

Expert Comment

by:nietod
Comment Utility
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
 

Author Comment

by:micah
Comment Utility
The comments where very good, the final proposed answer which came after the comments was a 'C'
0
 
LVL 22

Expert Comment

by:nietod
Comment Utility
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

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

  Included as part of the C++ Standard Template Library (STL) is a collection of generic containers. Each of these containers serves a different purpose and has different pros and cons. It is often difficult to decide which container to use and …
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

771 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now