View Full Version : String initialization issue
Raccoon29
18th June 2008, 17:50
Hi,
I'm trying to define some consts to use as interface for a class...
The point is, I have to define const arrays of strings (that is a matrix), but after many years of C++ programming, this is actually the first time that I have such a task... :o so I need a refresh...
The following code:
const char CONNECTIONS_AMOUNT=2;
const char DB[CONNECTIONS_AMOUNT-1][] = {"db1","db2"};
const char USERNAME[CONNECTIONS_AMOUNT-1][] = {"root1","root2"};
const char PASSWORD[CONNECTIONS_AMOUNT-1][] = {"admin","admin"};
const char HOST[CONNECTIONS_AMOUNT-1][] = {"localhost","localhost"};
doesn't work and the compiler complains:
multidimensional arrays must have bounds for all dimensions except the first
so following a suggestion I found on the net:
const char CONNECTIONS_AMOUNT=2;
const char DB[][CONNECTIONS_AMOUNT] = {"db1","db2"};
const char USERNAME[][CONNECTIONS_AMOUNT] = {"root1","root2"};
const char PASSWORD[][CONNECTIONS_AMOUNT] = {"admin","admin"};
const char HOST[][CONNECTIONS_AMOUNT] = {"localhost","localhost"};
and now the compiler complains:
initializer-string for array of chars is too long
(perhaps because so it expects arrays of 2 chars, that is CONNECTIONS_AMOUNT).
So, what is the simple solution and the stupid mistake for this?
Thank you for your time
mcosta
18th June 2008, 18:44
Try This
const int MAX_STRING_SIZE = 100;
const int CONNECTIONS_AMOUNT = 2;
const char DB [CONNECTIONS_AMOUNT][MAX_STRING_SIZE] = {"db1","db2"};
const char USERNAME[CONNECTIONS_AMOUNT][MAX_STRING_SIZE] = {"root1","root2"};
const char PASSWORD[CONNECTIONS_AMOUNT][MAX_STRING_SIZE] = {"admin","admin"};
const char HOST [CONNECTIONS_AMOUNT][MAX_STRING_SIZE] = {"localhost","localhost"};
Raccoon29
18th June 2008, 18:56
Yes, now it works, thanks
but isn't there a way to achieve that without specify the second size?
I remember (from school) that it was possible...
mcosta
18th June 2008, 20:33
I remember (from school) that it was possible...
I don't think it's possible.
The second size it's required to calculate the displacement to the base pointer.
For example
int matrix[][5] = {{1,2,3,4,5},{7,8,9,10,11}};
When you write
matrix[1][3]
the compiler generate
*(matrix + i * ROW_SIZE + j) --> *(matrix + 1 * 5 + 3) --> *(matrix + 8)
Raccoon29
23rd June 2008, 11:36
Mmh, yeah, you are right.
In fact I remembered wrong. :)
It is right like you explained.
Thank you!
PS: I would give you a forum "Thanks", but it seems that I can't because of a site bug I guess...
caduel
26th June 2008, 20:40
How about
const char CONNECTIONS_AMOUNT=2;
const char *DB[CONNECTIONS_AMOUNT] = {"db1","db2"};
const char *USERNAME[CONNECTIONS_AMOUNT] = {"root1","root2"};
const char *PASSWORD[CONNECTIONS_AMOUNT] = {"admin","admin"};
const char *HOST[CONNECTIONS_AMOUNT] = {"localhost","localhost"};
HTH
Raccoon29
22nd July 2008, 11:35
Hey yes, it works too :)
What is that?! I mean, I never saw this kind of code, why is it accepted from the compiler?
EDIT: well, actally now is the linker that complains for a very long serie of multiple declarations of the constant I declared in such a way... but are declarations from files like qglobal.h so maybe it's fighting versus qt library...actually I don't get what's going on here... :confused:
caduel
22nd July 2008, 12:07
you must not put such stuff in headers;
header:
enum { CONNECTIONS_AMOUNT=2 };
extern const char *DB[CONNECTIONS_AMOUNT];
extern const char *USERNAME[CONNECTIONS_AMOUNT];
.c-file
const char *DB[CONNECTIONS_AMOUNT] = {"db1","db2"};
const char *USERNAME[CONNECTIONS_AMOUNT] = {"root1","root2"};
const char *PASSWORD[CONNECTIONS_AMOUNT] = {"admin","admin"};
otherwise you get one instance per file where the .h file is included - unless the linker can sort out the duplicates.
To your question:
you defined a big "rectangle" of x*y bytes.
I define a vector of pointers to strings.
This is not the same (in memory), but if you actually want an array of strings, perhaps closer to your intentions.
Also, note that
const char PASSWORD[CONNECTIONS_AMOUNT][MAX_STRING_SIZE]
allocates CONNECTIONS_AMOUNT * MAX_STRING_SIZE bytes.
My code "allocates" (needs) CONNECTIONS_AMOUNT * sizeof(pointer) + the actually needed string sizes.
Finally, your code could allow the strings to be modified (without const), mine cannot, as "somestring" is of type const char*.
HTH
Raccoon29
22nd July 2008, 16:07
Oh, I see... yes, actually your code is the translation of what I intended to do ;) thank you so much!
Another question if possible:
otherwise you get one instance per file where the .h file is included - unless the linker can sort out the duplicates.
the included header has preprocessor filter:
#ifndef DB_DEFINES
#define DB_DEFINES
// ...consts definitions...
#endif
haven't they any sort of effect here?
caduel
22nd July 2008, 20:12
yes, those guards do help against multiple declarations.
they do not help against multiple definitions (same source tranlated multiple times into different .o files).
Check if you have problems compiling or linking. It should be linking.
Move the definitions into a .c file and use extern as I suggested. Should help.
Raccoon29
23rd July 2008, 17:22
In fact it is a linker problem and what you said is all right :)
I think to need to well study the difference between declaration and definition.
Thank you caduel for your explanations, from now I'll have to proceed alone :)
vBulletin® v3.7.1, Copyright ©2000-2008, Jelsoft Enterprises Ltd.