Structures with variable length array known at compile time

Hi, I need to develop a menu system for a project of mine. The menu will be displayed on a character LCD display driven by ARM7 Microcontroller. For this purpose i wish to construct a structure in C which will contain a the following - struct menu { int n (no. of elements in menu); char menu_items[20][q]; (This will contains the strings to be displayed on the LCD, 20 characters and n lines funcptr fptr; (Pointer to the corresponding menu function) }

the array "menu_items" will always have 20 character strings but the no. of them 'q' will differ from each menu screen. the no. of strings will be defined in "int n". I will be using this struct to implement const structs which i will be defining with all the menu screen information. From googling around i found variable length arrays cannot be implemented with in structures. I also found that the structure size should be known at compile time(i dont want to use malloc). My menu items will be known at compile time. how do i implement this? Thanks.

Reply to
aravind
Loading thread data ...

Declare the variable-length item as a pointer to a single element, is just one of several ways to get around this problem.

Reply to
larwe

It isn't entirely clear to me what you are attempting here. Assuming that there is nothing wrong with the structure of your code over and above the problem you are asking about that suggests that each struct menu holds a single menu selection whose text may or may not stretch over multiple lines. Is this correct?

If so what can't you do something along the lines of:

struct menu { int n; char *menu_items; funcptr fptr; }

In terms of a static initialisation you can basically forget that menu_items is a pointer - the compiler will allocate as much space as required and store a pointer to it within the structure. It is then up to you to determine how many lines the message requires, either by length or by paying attention to embedded '\n's.

This assume that the structure of your code is basically OK. If a single struct menu is supposed to accommodate an entire menu structure or sub menus you have wider problems and should post back with more details. I gave a few brief clues to this very problem earlier this year at:

formatting link

--
Andrew Smallshaw
andrews@sdf.lonestar.org
Reply to
Andrew Smallshaw

Exactly. I assume the the (upto) 20 lines display menu choices, and that funcptr is a function to get input that selects between actions. This doesn't sound reasonable, and I believe you need a set of 20 funcptrs to control access to the selected functions. Then I suspect a better organization would be:

struct anitem { execfunc selected; const char *menuline; }

and the menu can be defined with:

struct menu { anitem menuitem[]; };

Note that the size of the menu is controlled by the number of items stored in the menuitem array, with the last one being a NULL. menulines can be shared between various items, as can the execfunc. You need a definition for an execfunc, something like:

typedef int execfunc(int parm1, int parm2)

Then when you want to execute a menu, you load the appropriate pointer from the menu, call a display routine, call a selection routine, and execute. Assume menunum selects the appropriate thing from struct menu:

label: if (!display(menu[menunum])) { errdisplay(menunum); correctiveaction(); } else if ((p = selection(menu[menunum]))) { p(parm1, parm2); } else { errselect(menu[menunum]); goto label; } menunum = newmenu(); goto label;

Diddle as required. Untested. Note that the control structures don't contain wasted space, and that menulines and execfuncs can be reused as required. Also the language used is independent of the control structure.

--
 [mail]: Chuck F (cbfalconer at maineline dot net) 
 [page]: 
            Try the download section.
Reply to
CBFalconer

Sounds more complicated than it needs to be. For devices where all the menus need to be stored in ROM, I usually do use something similar to the printf() function:

lcd_menu("Current temperature %d degrees\n" "Setpoint %d degrees\n" "Humidity sensor %k{Outdoor,Indoor,Freezer}\n" "Return to main menu %z", &currtemp, &setpoint, &humidity_select, mainmenu_func );

Once you have your lcd_menu() function implemented, adding extra menus has almost no ROM overhead and all sizes are known at compile time. If you're even more ROM contrained you can put all the arguments in a const array so the compiler doesn't have to push them on the stack for each menu.

Reply to
Tom

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.