Pointer to string array in C
Solution 1
There are two way of working with array of characters (strings) in C
. They are as follows:
char a[ROW][COL];
char *b[ROW];
Pictorial representation is available as an inline comment in the code.
Based on how you want to represent the array of characters (strings), you can define pointer to that as follows
char (*ptr1)[COL] = a;
char **ptr2 = b;
They are fundamentally different types (in a subtle way) and so the pointers to them is also slightly different.
The following example demonstrates the different ways of working with strings in C
and I hope it helps you in better understanding of array of characters (strings) in C
.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define ROW 5
#define COL 10
int main(void)
{
int i, j;
char a[ROW][COL] = {"string1", "string2", "string3", "string4", "string5"};
char *b[ROW];
/*
a[][]
0 1 2 3 4 5 6 7 8 9
+---+---+---+---+---+---+---+------+---+---+
| s | t | r | i | n | g | 1 | '\0' | | |
+---+---+---+---+---+---+---+------+---+---+
| s | t | r | i | n | g | 2 | '\0' | | |
+---+---+---+---+---+---+---+------+---+---+
| s | t | r | i | n | g | 3 | '\0' | | |
+---+---+---+---+---+---+---+------+---+---+
| s | t | r | i | n | g | 4 | '\0' | | |
+---+---+---+---+---+---+---+------+---+---+
| s | t | r | i | n | g | 5 | '\0' | | |
+---+---+---+---+---+---+---+------+---+---+
*/
/* Now, lets work on b */
for (i=0 ; i<5; i++) {
if ((b[i] = malloc(sizeof(char) * COL)) == NULL) {
printf("unable to allocate memory \n");
return -1;
}
}
strcpy(b[0], "string1");
strcpy(b[1], "string2");
strcpy(b[2], "string3");
strcpy(b[3], "string4");
strcpy(b[4], "string5");
/*
b[] 0 1 2 3 4 5 6 7 8 9
+--------+ +---+---+---+---+---+---+---+------+---+---+
| --|------->| s | t | r | i | n | g | 1 | '\0' | | |
+--------+ +---+---+---+---+---+---+---+------+---+---+
| --|------->| s | t | r | i | n | g | 2 | '\0' | | |
+--------+ +---+---+---+---+---+---+---+------+---+---+
| --|------->| s | t | r | i | n | g | 3 | '\0' | | |
+--------+ +---+---+---+---+---+---+---+------+---+---+
| --|------->| s | t | r | i | n | g | 4 | '\0' | | |
+--------+ +---+---+---+---+---+---+---+------+---+---+
| --|------->| s | t | r | i | n | g | 5 | '\0' | | |
+--------+ +---+---+---+---+---+---+---+------+---+---+
*/
char (*ptr1)[COL] = a;
printf("Contents of first array \n");
for (i=0; i<ROW; i++)
printf("%s \n", *ptr1++);
char **ptr2 = b;
printf("Contents of second array \n");
for (i=0; i<ROW; i++)
printf("%s \n", ptr2[i]);
/* b should be free'd */
for (i=0 ; i<5; i++)
free(b[i]);
return 0;
}
Solution 2
What would be the correct way to solve this problem?
Well, the correct way would be to use a library specifically designed for dealing with multilanguage interfaces - for instance gettext.
Another way, though patchier, would be to use a hash table (also known as "dictionary" or "hash map" or "associative map" in other languages/technologies): Looking for a good hash table implementation in C
It's probably not the answer you were looking for, but you've asked the wrong question to the right problem.
Woodgnome
Updated on January 13, 2020Comments
-
Woodgnome over 4 years
Playing with pointers in
C
is fun (not really).I have several arrays of strings I want to declare in an easy way, preferably something like:
arrayOfStrings1 = {"word1", "word2", etc. }; arrayOfStrings2 = {"anotherword1", "anotherword2", etc. }; arrayOfStrings3 = etc. etc.
Something similar to a translation array (but not quite), so I want to be able to swap between these during runtime. For that I want a pointer
pointerToArrayOfStrings
that I can swap like:pointerToArrayOfStrings = arrayOfStrings1; doStuff(); pointerToArrayOfStrings = arrayOfStrings2; doSomeOtherStuff();
In my naive understanding of arrays of strings and pointers to these, this is what I tried:
// Danish transforms const unsigned char* da_DK[] = {"b","bb","c","c","cc","d","dd","e","f","ff","g","gg","h","hh","j","j","jj","k","k","kk","l","l","l","l","ll","m","mm","n","n","nn","p","pp","r","r","r","rr","s","s","s","ss","t","t","tt","v","v","vv","æ"}; // British english transforms const unsigned char* en_GB[] = {"a","a","a","a","a","a","a","a","a","a","a","a","a","age","ai","aj","ay","b","cial","cian","cian","dj","dsj","ea","ee","ege","ei","ei","eigh","eigh","f","f","f","g","g","gs","i","i","i","j","j","k","ks","kw","l","m","n","n","o","r","s","s","sd","sdr","sion","sion","sj","sj","tial","tion","tion","tj","u","u","u","u","w","ye","ye","z"}; // More languages.... const unsigned char** laguageStrings; // Assign language if (streq(language, "da-DK")){ laguageStrings= da_DK; } else if (streq(language, "en-GB")){ laguageStrings= en_GB; } else return 0; }
Language is a
char *
containing the language "en-GB", "da-DK" etc.,streq()
is just a home brewed (somewhat faster thanstrcmp()
) string comparison function.Long story short, depending on compiler this approach may work, report compiler warnings or compile, but give unexpected results.
What would be the correct way to solve this problem?
-
Woodgnome over 12 yearsSo if I wanted to define my array of strings as a
char *[COLS]
I am forced tomalloc()
and thenstrcpy()
? There is no way I can initialize it with a list of string like{"string1", "string2", ...}
? -
Woodgnome over 12 yearsSorry, that was supposed to be
char *[ROWS]
-
Sangeeth Saravanaraj over 12 years@Woodgnome Yes, you cannot assign a string to a
char[]
orchar *
like how you assign an integer value to an integer variable. For string you need to use string library functions likestrcpy()
-
Sangeeth Saravanaraj over 12 yearsCould you guys give an explanation for -1?!
-
Sangeeth Saravanaraj over 12 years@Woodgnome Thanks for choosing my answer. I hope it was helpful to you! .. If you like the answer, please feel free to upvote it! Thanks! :)
-
Woodgnome over 12 years@SangeethSaravanarj I upvoted as soon as you answered :P The downvote confuses me as well. With regard to my follow up question, I'll word it differently; I know I can not declare a char array
string[5];
and then later initialize it likestring = "test";
, but I've read that it is possible to initialize a read only string likechar *string = "test";
- if so, wouldn't it be possible to do the same withchar *b[ROWS] = {...}
in you example? Provided I don't need to make any changes to the string of course. -
Meninx - メネンックス over 9 yearsthe problem with this case
char *b[rows]= {"first","second" ...
is that if you want to change the string it will lead to unspecified behavior !! That's why it is better to use themalloc()
function !