Reputation: 630
What I'm trying to do is pretty straight forward in other languages. But I'm struggling with this in a C project and didn't find a right way to do it in my researches.
What I need to do is:
The code I have now is listed below.
#include <stdio.h>
const char *menu[] = {};
void populateMenu(){
// populate this menu with some itens
*menu = {
"New item A",
"New item B",
NULL
};
}
int main(int argc, const char * argv[])
{
// 1. print inicial menu
int menuAlen = sizeof(menu)/sizeof(*menu);
int i;
for(i = 0; i < menuAlen; i++){
printf("%s\n", menu[i]);
}
// 2. populate the menu
populateMenu();
// 3. print it again with new values
int menuBlen = sizeof(menu)/sizeof(*menu);
for(i = 0; i < menuBlen; i++){
printf("%s\n", menu[i]);
}
return 0;
}
I'm currently getting this error on build time.
main.c:16:16: Expected expression
Line 16 is the first line inside populateMenu function.
Can someone help me out with this? Thanks in advance.
Best. George.
Upvotes: 0
Views: 4237
Reputation: 108978
I hate global variables. I suggest you create the array inside main()
and pass it throughout your code as needed.
// #includes ...
// prototypes
int main(void) {
char menu[1000][80]; // space for 1000 strings each up to 79 characters long
size_t nmenu; // number of string in menu
nmenu = populate(menu); // change contents of array, set nmenu
menuprint(menu, nmenu); // print
return 0;
}
The rest of the program (the functions populate()
and menuprint()
) is up to you.
Note: the 1000
and 80
are large(ish) estimates. A better way to do it would be with dynamic memory allocation.
Upvotes: 0
Reputation: 40145
#include <stdio.h>
const char **menu = NULL;
void populateMenu(){
static const char *items[] = {
"New item A",
"New item B",
NULL
};
menu = items;
}
int menuLen(const char **menu){
int len = 0;
if(!menu) return 0;
while(*menu++)
++len;
return len;
}
int main(int argc, const char * argv[]){
// 1. print inicial menu
int menuAlen = menuLen(menu);
int i;
for(i = 0; i < menuAlen; i++){
printf("%s\n", menu[i]);
}
// 2. populate the menu
populateMenu();
// 3. print it again with new values
int menuBlen = menuLen(menu);
for(i = 0; i < menuBlen; i++){
printf("%s\n", menu[i]);
}
return 0;
}
Upvotes: 1
Reputation: 1
You should declare menu
as a pointer to [some array of] pointer strings:
char**menu;
You need to know the number of menu entries. So declare also
size_t nb_menu;
and have some way to compute it at runtime. (I leave that up to you, but you cannot use sizeof
which is a compile-time thing).
You then allocate in the heap, using calloc(3), that array:
menu = calloc (nb_menu+1, sizeof(char*));
if (!menu) { perror("calloc menu"); exit (EXIT_FAILURE); };
I'm doing nb_menu+1
because you probably want to NULL
terminate your menu
.
Now you could fill it, e.g.
menu[0] = "Some string";
or better yet, use strdup(3).
You should have a convention (and document it) about when and which pointers are into the heap -i.e; malloc
-ed or calloc
-ed and who should free
them.
You should later free(3) your pointers to avoid memory leaks. You can only free
a pointer obtained by malloc
or calloc
or strdup
(which calls malloc
) etc...
On Linux, you should learn how to use valgrind. Perhaps using Boehm Garbage Collector could help you. Certainly, understand what garbage collectors are and learn a lot more about C memory management.
Actually, you could use flexible array members and have your menu
be a pointer to
struct menu_st {
unsigned nb_entries;
char* entry_array[]; // nb_entries elements in the array
};
Read about the C memory model.
Don't forget to compile with all warnings and debug info (e.g. gcc -Wall -g
) and learn how to use the debugger (e.g. gdb
). Be very scared of undefined behavior.
Upvotes: 4