Character array initialization

Mar 29, 2020 at 1:24am
Hello guys,
I'm working with a class that contains an 2-D array of characters (char[][]).

In my constructor, I am taking in a string, with length a*b (dimensions of the character array), and assigning them to the array of characters.

For example, call the class StringToChar, which has a private char[3][3] as a class variable. Calling the constructor StringToChar("123456789") should initialize my char[][] as such:

1 2 3
4 5 6
7 8 9

The hard coding of [3][3] is not an issue as everything passed to the class has the same dimensions.

Here is my implementation of the constructor:

1
2
3
4
5
6
7
8
    const int arrSize = 3;
    StringToChar::StringToChar(const std::string& str) {

    for (int i = 0; i < arrSize* arrSize; i++) {

      charArr[static_cast<int>(i / arrSize)][i % arrSize] = str.at(i);
    }
  }


However, I get the following error in the line inside the for loop

 
    charArr[static_cast<int>(i / arrSize)][i % arrSize] = str.at(i);


Assigning to 'char **' from incompatible type 'const std::basic_string<char, std::char_traits<char>, std::allocator<char> >::value_type' (aka 'const char')

I had a couple questions about this:

1. The recommended fix in my IDE is to cast this as a char**. It resolves the issue but I do not understand why, and seems to me like just a way to cause more bugs down the line. So what should be the best fix here?

2. Why is a char[][] represented as a char**? Isnt a char** a pointer to a pointer to a char?

Thank you so much for any help!
Last edited on Mar 29, 2020 at 1:27am
Mar 29, 2020 at 1:52am
Edit: my brain went extra stupid here:

Sometimes an error actually exists on a line or two before. Look at your for loop. It should be:

    for (int i = 0; i < arrSize; i++)

Both i and arrSize are int, so all is good.

You managed to create a temporary that shadowed the class arrSize, if I am reading that correctly.

1
2
3
4
5
6
7
8
    const int arrSize = 3;
    StringToChar::StringToChar( const std::string& str )
    {
        for (int i = 0; i < arrSize; i++)
        {
            charArr[i / arrSize][i % arrSize] = str.at(i);
        }
    }

Hope this helps.
Last edited on Mar 29, 2020 at 2:02am
Mar 29, 2020 at 1:57am
Why should it be arrSize and not arrSize * arrSize? I want to parse through the whole string, which is of length 9
Mar 29, 2020 at 2:02am
Oh, you know, my brain failed me. You are right.

Give me a minute to play with my compiler and see if I can reproduce your error.

Edit. This is what I did.

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
#include <iostream>
using namespace std;

const int arrSize = 3;
char charArr[arrSize][arrSize];

void StringToChar(const std::string& str) {
  for (int i = 0; i < arrSize* arrSize; i++) {
    charArr[i / arrSize][i % arrSize] = str.at(i);
  }
}

int main()
{
  StringToChar( "123456789" );
  
  for (int y = 0; y < arrSize; y++)
  {
    for (int x = 0; x < arrSize; x++)
    {
      cout << charArr[y][x] << " ";
    }
    cout << "\n";
  }
}

What are you doing differently?
Last edited on Mar 29, 2020 at 2:08am
Mar 29, 2020 at 2:17am
Pretty much exactly the same thing. Not sure whats going on here. I deleted a Getter I had in my class and the error resolved itself. Weird.

However, now my getter has its own issue. The getter is for charArr

1
2
3
4

char[][] StringToChar::GetCharArr() {
    return charArr;
}


Does not work.

I get lots of errors:

Cannot initialize return object of type 'int' with an lvalue of type 'char [3][3]

Array has incomplete element type 'char []'

Brackets are not allowed here; to declare an array, place the brackets after the name


How do I format this getter?



Thank you so much for your time and help!! I am not sure why that issue self-resolved, seems weird.
Mar 29, 2020 at 2:25am
Would this be easier if I used an std::array instead of a c array?

Would that still decompose into pointers?
Mar 29, 2020 at 3:01am
No. The problem is that only the outermost dimension of an array type may be omitted, because it is really just another way of indicating a pointer.

That is: char[][20] is the same as (char[20])*. That was the source of your problem.

Typedefs help significantly when dealing with arrays and pointers.

1
2
3
4
5
6
7
8
// Array size
const int arrSize = 3;
// Array type
typedef char[arrSize][arrSize] array_type;
// Array variable
array_type charArr;
// Getter
array_type& GetCharArr() const { return charArr; }

Hope this helps.
Mar 29, 2020 at 3:09am
Thank you so much for all the help! I really appreciate it.
Topic archived. No new replies allowed.