'How to access different elements in char** in C?
I am given an array of strings in the form of a pointer to a pointer of a character (that is, char **). I wish to access each element in the array,
char **strings = {"hello", "bye", "whatusp"};
printf("%s\n", *(&strings));
printf("%s\n", *(&strings + 1));
I notice that the first printf() works, as it outputs "hello" for me, but the second doesn't output anything. The +1 does increment by 8 instead of 1, since the address is in bytes. How can I access an arbitrary element in such a double pointer?
Solution 1:[1]
Just as simple as:
char *strings[] = {"hello", "bye", "whatusp"};
printf("%s\n", strings[0]);
printf("%s\n", strings[1]);
printf("%s\n", strings[2]);
Solution 2:[2]
First of all, the line
char **strings = {"hello", "bye", "whatusp"};
is wrong. If you want to declare an array of 3 pointers to string literals, then it should be the following instead:
char *strings[3] = {"hello", "bye", "whatusp"};
In the previous line, you can omit the 3, because the compiler is smart enough to count the number of elements itself, since you are initializing the array.
The lines
printf("%s\n", *(&strings));
printf("%s\n", *(&strings + 1));
are also wrong, because when using printf with the %s format specifier, you must provide a pointer to a string, i.e. a char *. However, you are providing a char** instead in both lines.
The expression *(&strings) will evaluate to a char ** for the following reason:
The expression &strings will evaluate to a pointer to strings. Since strings itself is an array of 3 pointers to char, a pointer to strings is a pointer to an array of 3 pointers to char. Afterwards, you are applying the indirection operator * on this data type, so that the result of this operation is an array of 3 pointers to char. When passing this data type to printf, the array will decay to a pointer to the first element of the array, i.e. to a pointer to a pointer to a char (which is a char**).
You should simply write the following instead:
printf( "%s\n", strings[0] );
printf( "%s\n", strings[1] );
The expression strings[1] is equivalent to *(strings+1).
Solution 3:[3]
char **strings is a pointer to a pointer to char, not array of pointers to char, your compiler should have given you a warning anyways, if not you should enable them.
For that assignment to work, you will need to have an array of pointers, char *strings[] or if you want to use plain pointer notation (array notation is using pointer arithmetic in the background though), you could dynamically allocate memory for the first dimension.
#include <stdio.h>
#include <stdlib.h>
#define SIZE 3
int main(void)
{
char **strs = NULL;
if ((strs = malloc(SIZE * sizeof(char *))) == NULL) /* check malloc result */
{
exit(EXIT_FAILURE);
}
*strs = "hello"; /* assignment makes sense in this case but you cant modify the string since its read-only*/
*(strs + 1) = "bye";
*(strs + 2) = "whatsup";
for (int i = 0; i < SIZE; i++)
{
puts(*(strs + i));
}
/* Alternative that will allocate space for each string if you need to store them or modify them later */
/* for (int i = 0; i < 3; i++)
{
if ((*(strs + i) = malloc(YOUR_STRINGS_LENGTH)) == NULL)
{
exit(EXIT_FAILURE);
}
snprintf(*(strs + i), YOUR_STRINGS_LENGTH, "string");
}
*/
return 0;
}
Solution 4:[4]
I am given an array of strings in the form of a pointer to a pointer of a character (that is, char **)
There is no such thing: a char** is just a pointer. It is not an array.
if thing is char** then*thing is char* and **thing is, as declared, a char.
An array can be seen as a pointer, but a pointer is not an array.
note: the prototype for main is in general
int main( int argc, char** argv)
so what you need to do is the same as every C program gets from the system.
Example
To have char** as an array of pointers to char you must build it
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv)
{
char* array[] = {
"I", "wish", "to", "access", "each", "element",
"in", "the", "array"
};
int N = sizeof(array) / sizeof(char*);
printf("%d strings in total\n\n", N);
char** strings = (char**)malloc(N * sizeof(char*));
for (int i = 0; i < N; i=i+1)
*(strings+i) = *(array + i);
for (int i = 0; i < N; i=i+1)
printf("%3d %s\n", 1 + i, *(i + strings));
// pointer is not an array
char thing = '@';
char* p = &thing;
char** pp = &p;
printf("\n\nthing is '%c', *p is '%c', **pp is '%c'\n",
thing, *p, **pp);
return 0;
}
output
9 strings in total
1 I
2 wish
3 to
4 access
5 each
6 element
7 in
8 the
9 array
thing is '@', *p is '@', **pp is '@'
In particular note this lines
char** strings = (char**)malloc(N * sizeof(char*));
for (int i = 0; i < N; i=i+1)
*(strings+i) = *(array + i);
where is defined that strings is an area of the needed size and than the pointers are initialized to the strings of the input array.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | जलजनक |
| Solution 2 | |
| Solution 3 | |
| Solution 4 | arfneto |
