Solved

passing back an char[][]??

Posted on 1998-08-21
14
253 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 4
  • 2
  • +1
14 Comments
 
LVL 5

Expert Comment

by:ecw
ID: 1170857
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
ID: 1170858
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
ID: 1170859
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
Independent Software Vendors: 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!

 

Author Comment

by:micah
ID: 1170860
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
ID: 1170861
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
ID: 1170862
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
ID: 1170863
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
 

Author Comment

by:micah
ID: 1170864
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
ID: 1170865
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
ID: 1170866
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
ID: 1170867
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
ID: 1170868
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
ID: 1170869
The comments where very good, the final proposed answer which came after the comments was a 'C'
0
 
LVL 22

Expert Comment

by:nietod
ID: 1170870
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

Free Tool: Postgres Monitoring System

A PHP and Perl based system to collect and display usage statistics from PostgreSQL databases.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Unlike C#, C++ doesn't have native support for sealing classes (so they cannot be sub-classed). At the cost of a virtual base class pointer it is possible to implement a pseudo sealing mechanism The trick is to virtually inherit from a base class…
Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

761 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