Multidimensional Char Arrays

Hi,

I need to save Error and Warning messages to access them in Notification and Mail.

I did define them as single char Arrays now but for easier access I'd like to put them into ONE multidimensional array.

But my mind gets pretty messed up when trying to think about how they would be saved when they got more than 2 dimensions.

I like to have the following:

  1. The string consisting of chars
  2. A reference if its a warn or an error message
  3. Which of the Warn or error messages

So there are 2 Types of Message and 5 Messages each

For what I think it should look like:

char myarray[][2][5]={};

which is:

char myarray[CHARSofMESSAGE][MESSAGETYPE][MESSAGENUMBER]={};

Is this correct?

If so, how would the initialisation of this work (given fixed messages)?
I know how to define 2 dimensional Arrays but how about this?

Or am I thinking the wrong way and wasting much program space?

are you overthinking it?

char* warnings[] = {"Warning 1", "Warning 2"};
char* errors[] = {"Error One", "Error two"};

DAMN!

I looked for nearly an hour bbut couldn't find the answer anywhere, now just after posting I slightly changed my search keyword and found it....

So for anyone having the same question:

char card[2][3][15]={ {"iron","man", "contagious"},
                      {"iron","man", "contagious"}};

Using pointers would reduce the amount of memory needed. Your example uses 90 bytes to store 40 characters.

PaulS:
Using pointers would reduce the amount of memory needed. Your example uses 90 bytes to store 40 characters.

yup.... like this:

char* warnings[][3] = { 
  {"iron","man", "contagious"},
  {"iron","man", "contagious"}
};
char Fehlermeldungen[2][][]       // Array Pos 1 = [0]Error/[1Warnung],  Pos 2 = Nummer der Warnung/Error -1 ,  Pos 3 = Chars
{
  {
  "Pflanzen: Fehler Feuchtigkeitsmessung! Dringend handeln! - Pumpen deaktiviert!", 
  "Pflanzen: Fehler Wasserstandssmessung! Dringend handeln! - Pumpen deaktiviert!", 
  "Pflanzen: Fehler Düngerwassermessung! Dringend handeln! - Pumpen deaktiviert!", 
  "Pflanzen: Fehler Pumpen-Timeout! Dringend handeln! - Pumpen deaktiviert!"
  },
  {
  "Pflanzen: Warnung! 30% Wasserstand!", 
  "Pflanzen: Warnung! 20% Wasserstand!", 
  "Pflanzen: Warnung! 10% Wasserstand!", 
  "Pflanzen: Warnung! Kalibration notwendig!", 
  "Pflanzen: Wassertank befüllt!"
  }
};

This is what I came up with...
How would one do that with pointers and why does it need less mem?
(was it because of the value lenghts I enered? They were just for thinking about the example)

Should work with empty brackets and use the minimum possible memory right?

OH MAN! This "you can only answer in 5 minutes sucks!" How should one use the forum to reply or modyfy own posts this way

How would one do that with pointers

BulldogLowell already showed that.

and why does it need less mem?

Because a pointer points to a box of the right size. Your boxes are all the same size, large enough to hold the longest string provided.

If you have 5 strings that are 10 characters, and one that is 120 characters, using your method, you need 6 containers that can hold 120 characters each (for a total of 600 bytes). Using pointers, you'd point to 1 container that could hold 120 characters and 5 containers that could hold 10 characters (for a total of 170 characters).

ah ok, thanks!

Gorkde:
ah ok, thanks!

aside from the fact that your array won't even compile, Paul points out that using a pointer to a char array is simpler and more compact:

char* Fehlermeldungen[][5]  =
{
  {
  "Pflanzen: Fehler Feuchtigkeitsmessung! Dringend handeln! - Pumpen deaktiviert!", 
  "Pflanzen: Fehler Wasserstandssmessung! Dringend handeln! - Pumpen deaktiviert!", 
  "Pflanzen: Fehler Düngerwassermessung! Dringend handeln! - Pumpen deaktiviert!", 
  "Pflanzen: Fehler Pumpen-Timeout! Dringend handeln! - Pumpen deaktiviert!",
  NULL
  },
  {
  "Pflanzen: Warnung! 30% Wasserstand!", 
  "Pflanzen: Warnung! 20% Wasserstand!", 
  "Pflanzen: Warnung! 10% Wasserstand!", 
  "Pflanzen: Warnung! Kalibration notwendig!", 
  "Pflanzen: Wassertank befüllt!"
  }
};

I added the empty char array (NULL) because the size of the first group is four pointers, the second is 5. making the array of two sets of five pointers fits both, adding the NULL is a way of remembering later that the 5th in the first set is empty "on purpose"

Then you need to put all of this into PROGMEM...

EDIT:

So read this and learn about all of this above:

BulldogLowell:
aside from the fact that your array won't even compile, Paul points out that using a pointer to a char array is simpler and more compact:

char* Fehlermeldungen[][5]  =

{
  {
  "Pflanzen: Fehler Feuchtigkeitsmessung! Dringend handeln! - Pumpen deaktiviert!",
  "Pflanzen: Fehler Wasserstandssmessung! Dringend handeln! - Pumpen deaktiviert!",
  "Pflanzen: Fehler Düngerwassermessung! Dringend handeln! - Pumpen deaktiviert!",
  "Pflanzen: Fehler Pumpen-Timeout! Dringend handeln! - Pumpen deaktiviert!",
  NULL
  },
  {
  "Pflanzen: Warnung! 30% Wasserstand!",
  "Pflanzen: Warnung! 20% Wasserstand!",
  "Pflanzen: Warnung! 10% Wasserstand!",
  "Pflanzen: Warnung! Kalibration notwendig!",
  "Pflanzen: Wassertank befüllt!"
  }
};




I added the empty char array (NULL) because the size of the first group is four pointers, the second is 5. making the array of two sets of five pointers fits both, adding the NULL is a way of remembering later that the 5th in the first set is empty "on purpose"

Then you need to put all of this into PROGMEM...

Thanks!

The NULL is not neccessary right? I won't need it since the messages would be updated once more are needed. So the numbers of them may change anyway.

I'm really having problems understanding Array with more than 2 Dimensions as well as how Pointers work.

I read about already I know they point to the adress but cant understand whats the difference for example if you access a Array like

var = myArray[7][1];

Thats also pointing to the memory of that value right? For my brain that's pretty confusing!

Gorkde:
The NULL is not neccessary right? I won't need it since the messages would be updated once more are needed. So the numbers of them may change anyway.

adding the NULL pointer isn't necessary, BUT when you look back at this later, you may have a hard time remembering why your 2 x 5 char* array is actually missing one element (in your example). Put the NULL pointer in the array says "hey I meant to do this!!!".

I'm really having problems understanding Array with more than 2 Dimensions as well as how Pointers work.

I read about already I know they point to the adress but cant understand whats the difference for example if you access a Array like

var = myArray[7][1];

Thats also pointing to the memory of that value right? For my brain that's pretty confusing!

so read up on pointers and learn! But first read the link I provided and get all of these char arrays into PROGMEM. You are unnecessarily consuming SRAM, you should put all of those string literals into program space.

BulldogLowell:
adding the NULL pointer isn't necessary, BUT when you look back at this later, you may have a hard time remembering why your 2 x 5 char* array is actually missing one element (in your example). Put the NULL pointer in the array says "hey I meant to do this!!!".

so read up on pointers and learn! But first read the link I provided and get all of these char arrays into PROGMEM. You are unnecessarily consuming SRAM, you should put all of those string literals into program space.

Progmem:
Thanks for the link, didnt know that page. Already read about the f() but was thinking if I should care at all since it should be enough anyway.

Pointers:
I tried many times to understand multidimensional Arrays/Pointers but cant my mind somehow not wrap around.

Could you please use the example i gave and try to explain why this is other then accessing the value by a pointer?

To explain my problem....

After some Basic on the C64 back then I wrote programs in Assembly on Amiga.
So I know how memory is organnized.

but when I point to an address where the value is stored (pointer) that should be in my mind the same as

var = myArray[7][1];

because isn't

myArray[7][1]

also just telling the compiler to look where in menmory that value is and read it?

I somehow can't understand the difference!

Could you please use the example i gave and try to explain why this is other then accessing the value by a pointer?

Arrays and pointers are VERY closely linked. Every array is a pointer.

Arrays can be arrays of pointers. In that case, every pointer can point to a different length string (or different sized array).

The data in the array is accessed exactly the same way, regardless of whether the array is a "simple" type or a pointer, because arrays are pointers.

Not using arrays of pointers, though, means that all the dimensions of an array must be defined, and are the same for every element in the array.

char [rows][cols] = { { "one", "two", "three" }, "Ahmad", "Nicholas is a friend", "Bob" } };

In this array, assuming that rows and cols are defined and properly initialized, the value for rows needs to be 2. The value for cols needs to be large enough to hold "Nicholas is a friend", even though most of entries in the array are much smaller than that.

Multi-dimension arrays are just arrays of arrays. Seeing that arrays and pointers are so closely linked makes it obvious why this is so.

Gorkde:
After some Basic on the C64 back then I wrote programs in Assembly on Amiga.

Are those new? I haven't seen them yet.

it has been a while since I went to Uni, I guess the really cool stuff happened later.

:wink:

PaulS:
Multi-dimension arrays are just arrays of arrays. Seeing that arrays and pointers are so closely linked makes it obvious why this is so.

I really got problems with that :frowning:

So the array we had above doesn't contain the values but their memory adresses right?
But they need to be stored somwhere anyway and isnt the char array storing it and pointing me to where it's stored when I use the example I gave?

isn't

myArray[7][4]

also pointing to row 7 col 4's memory adress, looking up the data and giving it back?

could you tell me how you would access that value with the pointer then?

*myArray points to the mem where the first value is stored right?
But how to access the one in r6 c2 for example?

Maybe I then understand the difference....

when I use the example I gave?

isn't

myArray[7][4]

also pointing to row 7 col 4's memory adress

No, it is not "pointing to" row 7, column 4's memory address. It IS row 7, column 4's memory address, and the value at that memory location is directly accessible. This assumes, of course, that the type of myArray is not char *.

Lets say abc at position 1 contains 20 and is at memory address 400.

abc[1] would return 20

*(abc+1) would return 400? Correct?

So how would I access the value then?

abc+1 probably right?

In essence its nothing other than an Array but the only difference being an array has given size and this fixed block resides somewhere in memory to be accessed.

While the pointer points as the array to a block of data in the memory but the block doesn't have to be specific dimensions.

For me defining 10 values as array and having them into memory is somewhat the same as having an block of memory with the same data but in different sizes.

Might that be my problem?

Lets say i want to store this table

A, B, C,
D, E, F, G, H

The Array would put this block in memory

A, B, C, 0, 0, D, E, F, G, H

and myArray[4] would in essence look up the pointer for Value D (6 in this case) , read D at that memory address and return it.

Done with pointer the part of the memory would look like this right? No necessary 0s for filling

A, B, C, 0, 0, D, E, F, G, H

But in essence its nearly the same right?
You would just have other places where the data resides because there's no 0s in that block.
And you need to for the data at this address with the pointer.

Correct that far?

Lets say abc at position 1 contains 20 and is at memory address 400.

I don't understand this statement, so I can't comment on the rest of the reply.

I do understand something like:

   char abc[] = "something";

Then, we can make assumptions about where abc is located in memory and what happens when you use offsets and pointer notation and all kinds of other things.