Char type is giving me headaches :(

I am trying to learn how to pass char, char*, char*[] into functions and such operations but.....I just don't understand!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Parent{
   private:
      char* text[]; 
      // I want to have an array of char pointers so I can output
      // EX. text[0]="Hello", text[1]="World" etc
   public:
      Parent( char* t[] ){
       //Constructor takes char* [] type to I can initialize 'text'
      }
      char* getText()[ return text; ] //I am not sure how to return 'text'
}

int main(){
   char * input[] = {"Hello", "World"}; 
   Parent object = new Parent(input);
}


The error message I am getting is giving me a headache about "char*" not "char**" or can't assign "char*" to "char[0]"

Can someone give me some guidance?
Last edited on
Consider using std::string instead. https://cal-linux.com/tutorials/strings.html

For example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <string>

class parent
{
    private: std::string txt ;

    public:

        explicit parent( const std::string& text ) : txt(text) {}
        
        explicit parent( const char* cstr ) : txt( cstr == nullptr ? "" : cstr ) {}

        const std::string& text() const { return txt ; }
};

int main()
{
    const parent par( "hello world!" ) ;
    std::cout << par.text() << '\n' ;
}
If you absolutely must use C-style strings and arrays, then text is an array of char*. You can't return it as a single char*, any more than you could return an arrtay of int as a single int.

An array decays to a pointer of the type of element it contains. An array of int would decay to an int*. Similarly, an array of char* decays to a pointer to char*, i.e. char** .

But, as JLBorges says, in C++ we would prefer to use std::string instead of C-style strings (and also, std::vector instead of C-style arrays).
Last edited on
patching up what you had:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

class Parent
{
   private:
      char** text; 
      // I want to have an array of char pointers so I can output
      // EX. text[0]="Hello", text[1]="World" etc
   public:
      Parent( char** t )
	  {
       text = t;
      }
      char** getText(){ return text; } //I am not sure how to return 'text'
};

int main()
{
   char * input[] = {"Hello", "World"};  //you are cheating a bit, nonstandard compiler extension
   // you can't convert literals to char* in standard c++.    
   //Parent object = new Parent(input);  //this looks like another similar language ;)
   Parent object(input);
   cout << object.getText()[0] << " " << object.getText()[1]  << endl;
}


^^ this feels like taking the area of a rectangle with calculus.

the big take-aways..
1) char * bad. string good.
2) the type of get text and the type of text need to match, and they need to be something the compiler can work with at compile time. [] empty/flexible sized array syntax is tricky to get working outside of trivial examples, because there are rules about how arrays can be passed around. Pointers can avoid these rules, but you have to be very careful about how you do this. The better solution is to pass containers (and string is a container) around which avoid these aggravations. I like C-arrays, but one of their biggest frustrations / weaknesses is passing them with more than one dimension: it is harder than it should be to do that, and you need some background to do it. Its better if you just avoid that issue and pass containers instead. You can make these things work, of course, just be aware that you have lapsed into C an will have to be a lot more hands-on to pull it off.
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <iostream>
#include <cstring>
using namespace std;

class Parent
{
private:
   char** text; 
   int size;
public:
   Parent( const char** t, int words )
   {
      size = words;
      text = new char*[size];
      for ( int i = 0; i < size; i++ )
      {
         text[i] = new char[strlen(t[i]) + 1];
         strcpy( text[i], t[i] );
      }  
   }
   ~Parent()
   {
      for ( int i = 0; i < size; i++ ) delete [] text[i];
      delete [] text;
   }
   char** getText(){ return text; }
};


int main()
{
   const char * input[] = {"Hello", "World"};
   Parent object( input, 2 );
   cout << object.getText()[0] << '\n' << object.getText()[1]  << '\n';
}

Hmm, occurs to me it could probably do with a copy constructor and assignment operator as well. Some other day.

Hello
World



I think everybody wants you to use the string & vector version:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <string>
#include <vector>
using namespace std;

class Parent
{
private:
   vector<string> text; 
public:
   Parent( const vector<string> &input ) : text( input ){}
   vector<string> getText(){ return text; }
};


int main()
{
   vector<string> input = { "Hello", "World" };
   Parent object( input );
   cout << object.getText()[0] << '\n' << object.getText()[1]  << '\n';
}
Last edited on
Topic archived. No new replies allowed.