A way of ending a char
array before it becomes full is to put '\0'
at end, like-
single_str[5] ='\0';
Then how to end a 2D char
array in that way?
In practice, you should in C avoid thinking of 2D arrays. Stricto sensu, the C language don't know about 2D arrays, only about arrays of arrays (fixed length, all of the same size) or about arrays of pointers (or array of aggregates or scalars).
You might use an array of string pointers. C strings are conventionally ended by a zero byte. Here is an example of constant array (of constant strings, i.e. const char*
pointers) ended by a NULL
string
const char*const arrstr[] = {
"Hello",
"Nice",
"World",
NULL
};
On my machine, sizeof(const char*)
is 8, so sizeof(arrstr)
is 32; and sizeof("Nice")
is 5.
You could print all the array members with
for (const char*const* p = arrstr; *p; p++) printf("%s\n", *p);
You could use in C99 a structure ending with a flexible array member, e.g.
struct my_string_array_st {
unsigned len;
char* arr[]; // array of len pointers */
};
then you might have a constructor function which build such string arrays with empty content like
struct my_string_array_st* make_string_array(unsigned ln) {
struct my_string_array_st*p
= malloc(sizeof(struct my_string_array_st) + len*sizeof(char*));
if (!p) { perror("malloc"); exit(EXIT_FAILURE); };
p->len = ln;
for (unsigned ix=0; ix<ln; ix+) p->arr[ix] = NULL;
return p; }
you'll then decide (this is your convention to follow) that each string inside is heap-allocated with strdup
- so you don't have two aliased pointers inside. Here is the function to set a string (and release the previous one, if needed)
void
set_string_array(struct my_string_array_st*p, unsigned ix, const char*str) {
if (!p || ix>=p->len) return;
free(p->arr[ix]);
char* s = NULL;
if (str) {
s = strdup(str);
if (!s) { perror("strdup"); exit(EXIT_FAILURE); };
};
p->arr[ix] = s;
}
(recall that you are allowed to free(3) a NULL
pointer; it is a no-op)
and here is a destructor function, releasing all the internal strings.
void destroy_string_array(struct my_string_array_st*p) {
if (!p) return;
unsigned l = p->len;
for (unsigned ix=0; ix<l; ix++) free(p->arr[ix]);
free (p);
}
Of course, here is an accessor function:
const char* nth_string_array(struct my_string_array_st*p, unsigned ix)
{
if (!p || ix>=p->len) return NULL;
return p->arr[ix];
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With