Forums

Structures with variable length array known at compile time

Started by aravind September 14, 2008
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.
> { > =A0 =A0 =A0int n (no. of elements in menu); > =A0 =A0 =A0char menu_items[20][q]; (This will contains the strings to be > displayed on the LCD, 20 characters and n lines > =A0 =A0 =A0funcptr fptr; (Pointer to the corresponding menu function) > > }
Declare the variable-length item as a pointer to a single element, is just one of several ways to get around this problem.
On 2008-09-14, aravind <aramosfet@gmail.com> wrote:
> 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.
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: http://groups.google.co.uk/group/comp.arch.embedded/msg/8a94ed50132e0bb2 -- Andrew Smallshaw andrews@sdf.lonestar.org
Andrew Smallshaw wrote:
> aravind <aramosfet@gmail.com> wrote: > >> 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. > > 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?
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]: <http://cbfalconer.home.att.net> Try the download section.
In article <13631240-3f6e-4d35-987e-4e0fca820732@w24g2000prd.googlegroups.com>, aravind <aramosfet@gmail.com> wrote:
>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.
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.