This is what I expect my string array s to be after the program is run: {"#0", "#1", "2"}.
This is what I am getting: {"#2", "#2", "2"}.
How do I modify this code so that I can get {"#0", "#1", "#2"} in the main after the function is executed?
What am I doing wrong? Please help.
#include <stdio.h>
void func(char **s){
for(int i=0; i<3; i++){
char buf[10];
snprintf(buf, 10, "#%d",i);
s[i]=buf;
}
}
int main()
{
char *s[3];
func(s);
for(int i=0; i<3; i++){
printf("%s", s[i]);
}
return 0;
}
@Chris’s answer tells you what is wrong.
To fix it, you have options. The simplest is to make the argument array have strings (char arrays) that are big enough for your uses:
#define MAX_STR_LEN (9+1) // Every string’s capacity is 9+1 characters
void func(size_t n, char array_of_string[][MAX_STR_LEN])
{
for (size_t i=0; i<n; i++)
{
snprintf(array_of_string[i], MAX_STR_LEN, "#%d", (int)i); // use the extant string
}
}
int main(void)
{
char array_of_string[3][MAX_STR_LEN] = {{0}}; // Array of 3 strings
func(3, array_of_string);
...
return 0;
}
If you want to play with dynamic char *
strings, life gets only a little more complicated:
void func(size_t n, char *array_of_string[])
{
for (size_t i=0; i<n; i++)
{
free(array_of_string[i]); // free any pre-existing string
array_of_string[i] = calloc( 10, 1 ); // allocate our new string
if (!array_of_string[i]) fooey(); // always check for failure
snprintf(array_of_string[i], 10, "#%d", (int)i); // use the new string
}
}
int main(void)
{
char *array_of_string[3] = {NULL}; // Array of 3 dynamic strings, all initially NULL
func(3, array_of_string);
...
for (size_t i=0; i<3; i++) // Don’t forget to clean up after yourself
free(array_of_string[i]);
return 0;
}
Ultimately the trick is to manage the size of your strings, remembering that a string is itself just an array of char
. You must ensure that there is enough room in your character array to store all the characters you wish. (Good job on using snprintf()
!
Also remember that in C any argument of the form array[]
is the same as *array
. So our functions could have been written:
void func(size_t n, char (*array_of_string)[MAX_STR_LEN])
or
void func(size_t n, char **array_of_string)
respectively. The first is an uglier (harder to read) syntax. The second is nicer, methinks, but YRMV.
Finally, if you are using C99 (or later) you can tell the compiler that those arguments are, actually, arrays:
void func(size_t n, char array_of_string[n][MAX_STR_LEN])
or
void func(size_t n, char *array_of_string[n])
MSVC does not support that syntax, though, and probably never will, alas.