1

i have the following code in a function

char MenuOptions[7][200];
strcpy(MenuOptions[0], "Create New / Modify Existing Customer");
strcpy(MenuOptions[1], "Create New / Modify Existing Product");
strcpy(MenuOptions[2], "List All customers");
strcpy(MenuOptions[3], "List All Products");
strcpy(MenuOptions[4], "Batch Update of New Stock");
strcpy(MenuOptions[5], "Create Customer Order");
strcpy(MenuOptions[6], "View Last Order for Customer");
switch (displayMenu("Main Menu", MenuOptions, 7, TRUE)) {
etc....

and

char displayMenu(char *name, char *options[], int menuLength,
    enBoolean QuitEnabled) {

    int i;
    printf("%s: \n", name);
    for (i = 0; i < menuLength; i++) {
        printf("\t %d %s.\n", (i + 1), options[i]);
    }
    if (QuitEnabled == TRUE)
        printf("\t Q. Quit\n");
etc

once the displayMenu method is entered though, the MenuOptions array seems to be lost from memory. I tried seeing what options[i] is through the expression window in eclipse and it says that it's "out of bounds" as a value

3
  • Posting etc as your code doesn't really help anything. Why not just post the actual code instead? Commented Dec 10, 2012 at 19:13
  • @netcoder, the use of ect seems completely appropriate, if not preferable. The error he is reporting seems to be happening before those lines would ever be reached. Posting to much code just makes it harder to read. Commented Dec 10, 2012 at 19:15
  • char* MenuOptions[] = {"Create New / Modify Existing Customer", ... , "View Last Order for Customer"}; but you need to post the return section of displayMenu ... it should be an integer value Commented Dec 10, 2012 at 19:23

4 Answers 4

1

First and foremost, turn on warning options in your compiler. Your compiler should have warned you there was a type mismatch.

MenuOptions is an array of seven arrays of 200 char. When displayMenu is called, and MenuOptions is passed as a parameter, MenuOptions is automatically converted from an array to a pointer to the first of the seven arrays of 200 char.

In displayMenu, the options parameter is declared with char *options[]. This means that options is an array of pointers to char. In function parameters, [] is special; it suggests that an array will be passed for this parameter, but the array is actually passed by the address of its first argument. Thus, this declaration says that options is a pointer to the first of some number of pointers to char.

So, you are passing a pointer to the first of seven arrays of 200 char, but the function expects to receive a pointer to the first of some number of pointers to char.

One way to fix this is to change the declaration of options to char (*options)[200]. This says that options is a pointer to (the first of) arrays of 200 char.

A better way to fix it may be to change MenuOptions:

static const char *MenuOptions[] =
{
    "Create New / Modify Existing Customer",
    "Create New / Modify Existing Product",
    "List All customers",
    "List All Products",
    "Batch Update of New Stock",
    "Create Customer Order",
    "View Last Order for Customer",
};

(You do not need “7” in the brackets because the compiler will count the strings for you.)

Then you do not need to change the declaration of options, except that I have added const:

char displayMenu(char *name, const char *options[], int menuLength,
    enBoolean QuitEnabled) {…

Now:

  • MenuOptions is an array of seven pointers to strings (arrays of char). It is passed as a pointer to pointers to strings, and options is a pointer to pointers to strings, so the types match.
  • MenuOptions does not take more space than required. Before, it was defined with 200 characters for each string. Now, each string takes only as much space as it needs (plus a null character at the end and a pointer to the string in the MenuOptions array).
  • const is added to avoid accidentally changing the strings.
  • MenuOptions is declared static, so that it is initialized at compile time, and you do not need to copy strings into it at run time.

Finally, you can replace the “7” in the call to displayMenu with sizeof MenuOptions / sizeof *MenuOptions. This divides the size of the array by the size of an element of the array, giving the number of elements in the array. This is preferred over hard-coding a constant because it eliminates the possibility that somebody might change the size of the array without changing the hard-coded constant.

Sign up to request clarification or add additional context in comments.

6 Comments

when it comes to the printf however it's still failing. using the (options)[200] should i call options[i] in the printf. And just to verify. passing MenuOptions is right (not &MenuOptions) right?
@mangusbrother: The code works for me in both the ways I have described above. You may have another error. In order for people to help, you must show code that is complete enough for other people to copy and execute.
@mangusbrother: Yes, you would pass just MenuOptions, not &MenuOptions.
it's still not printing the values. Minimized the code: displayMenu(char *name, const char *options[], int menuLength) { int i; printf("%s: \n", name); for (i = 0; i < menuLength; i++) { printf("\t %d %s.\n", (i + 1), options[i]); } } int main(){ static const char *MenuOptions[] = { "Create New / Modify Existing Customer", "Create New / Modify Existing Product", "List All customers", "List All Products", "Batch Update of New Stock", "Create Customer Order", "View Last Order for Customer", }; displayMenu("Main Menu", MenuOptions,7); }
@mangusbrother: When I compile and execute that, it prints the seven strings. Things to check: (0) Did you compile and execute the new code, not old code? (1) If you include printf("Hello, world.\n"); as the first line in main, does “Hello, world.” appear when you run the program? (2) Does anything appear when you run the program? Is there an error message, garbage output, or anything at all? Is there a window displayed where output would appear?
|
1

The type of options in displayMenu needs to be char (*options)[200]. not char *options[].

Except when it is the operand of the sizeof. _Alignof, or unary & operators, or is a string literal being used to initialize an array in a declaration, an expression of type "N-element array of T" will be converted ("decay") to an expression of type "pointer to T". In this case, MenuOptions is a 7-element array of 200-element arrays of char; by the rule above, it will decay to an expression of type "pointer to 200-element array of char".

As written, the type of options is char **; options[i] gives you the i'th pointer to char after the base of the array, not the i'th 200-element array of char.

Comments

0

Change your input type:

char displayMenu(char *name, char *options[], ...

to reflect that it's a multidimensional array:

char displayMenu(char *name, char options[][200], ...

Other options that will work:

char displayMenu(char *name, char options[7][200], ...

char displayMenu(char *name, char (*options)[200], ...

The main point is when passing multidimensional arrays all dimensions past the first, need to be passed as well.

Comments

0

One option:

char displayMenu(char *name, char options[][200], int menuLength, enBoolean QuitEnabled) 

1 Comment

Considering that only passes one string, it would break the OP's displayMenu function which is printing strings %s in a loop

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.