Question: C string/structure confusion

Chris Torek chris at mimsy.umd.edu
Sun Apr 8 08:52:00 AEST 1990


In article <78932 at tut.cis.ohio-state.edu>
dan_waylonis at gryphon.cis.ohio-state.edu writes:
>I am having a problem with loading a structure with a string:

No, actually, you are having a different problem.  Anyway:

>typedef struct menu_struct {
>	int	num_items;
>	char	**item; 	/* this may be wrong, but I want a arbitrary
>				   number of items of arbitrary length */
>} menu_td;

The type for `item' is the best one for `zero or more pointers to char',
each of which points to zero or more characters.  If `item' is set to
the address of the first of a sequence of pointers, each of which points
to the first of a sequence of characters that are ended by a '\0', then
`item[i]' (for any valid, i.e., in-range, integral i) can be called a
`string of arbitrary length'.

>menu_td  menu[5];		/* want 5 menus */
>
>	menu[0].item[0] = "Item0";
>
>But this last line doesn't work...

This is a type mismatch.  menu[0].item[0] has type `pointer to char';
its value is that of the first of the pointers to which menu[0].item
has been set to point.  Since menu[0].item has not been set to point
anywhere, this value is either garbage (if menu[] is an automatic varible)
or a nil of type `char **' (if menu[] is a global or static variable).
In either case, it does not point to at least one pointer.

So, the first problem is to set menu[i] (for 0 <= i <= 4) so that it
has a valid `num_items' field and a valid `items' field:

	int i;

	for (i = 0; i < 4; i++) {
		menu[i].num_items = 0;
		menu[i].items = NULL;
	}

Now each menu has zero items, and a nil pointer of type `char **' (no
matter which of the two proper standard definitions of `NULL' are used).
(This loop is unnecessary if menu[] is global or static.  It is also
unnecessary if you can prove that menu[i] will not be used before it
is set to some valid value.)

Next, suppose that menu[0] has a fixed size, 4, and should have 4 `items':

	menu[0].num_items = 4;

menu[0].items must now be set to point to the first of at least four
contiguous objects of type `pointer to char'.  One easy way to do this
is:

	{
		static char *menu0[4] = { "foo", "bar", "baz", "raz" };
		menu[0].items = &menu0[0];
	}

Now menu[0].items points to the first element of the four-element array
`menu0'.  Each element of that array has type `pointer to char', and
each points to a (read-only) `C string' (i.e., array of one or more
characters, ended by '\0') allocated somehow by the compiler.

If, instead, the `strings' are to be read from an external file, the
process is more complicated; I will not go into this here.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris at cs.umd.edu	Path:	uunet!mimsy!chris



More information about the Comp.lang.c mailing list