Simple console mode menu handling

Started by DMac, July 14, 2011, 08:45:52 PM

Previous topic - Next topic

DMac

Menu driven console applications couldn't be easier than with this simple menu handler.

This Code:
int main(int argc, char *argv[])
{
    MENU_ITEM items[] =
    {
        _T("Item 1"), &item1Handler,
        _T("Item 2"), &item2Handler,
        _T("Exit"), &exitHandler
    };

    while(_fContinue)
    {
        Console_Clear();
        _tprintf(_T("Please choose an option.\n"));
        ConsoleMenu_Show(items, NELEMS(items));
    }
    return 0;
}

Gives you this menu:
QuotePlease choose an option.
[1] Item 1
[2] Item 2
[3] Exit

Menu choices can easily be nested and project code, organized into callbacks, becomes easy to maintain.
No one cares how much you know,
until they know how much you care.

CommonTater

VERY nice.... simple, effective and easily implemented.

Good work.

Vortex

Code it... That's all...

grooves

Hi,

where are all variables, like _fContinue and functions, i.e. Console_Clear defined ?
which header file ?

Thanks and regards,
grooves

grooves

sorry, I didn't found the Zip file,
and tried just the code snippet,

it works,
Thanks,
grooves

vedro-compota

well done) but there's a question - here's a code from your main() func. =
void item1Handler(void)
{
    _tprintf(_T("You have chosen item 1.\n"));
    _gettchar();
}

what does "_T" mean? where it from? and why your start with  "_" in _tprintf  _gettchar ? and i can't find the definition of this both functions...

Stefan Pendl

_T() is a shorthand for TEXT().

The second functions are not standard C, so they are preceded by an underscore.
They are documented in the help file topic "tchar.h".
Both function names are the generic ones for "wprintf" and "getwchar".
---
Stefan

Proud member of the UltraDefrag Development Team

CommonTater

Quote from: vedro-compota on October 19, 2011, 06:47:11 PM
well done) but there's a question - here's a code from your main() func. =
void item1Handler(void)
{
    _tprintf(_T("You have chosen item 1.\n"));
    _gettchar();
}

what does "_T" mean? where it from? and why your start with  "_" in _tprintf  _gettchar ? and i can't find the definition of this both functions...

the whole _T thing is about unicode... in Windows thats wchar_t ... an unsigned short int for UTF16LE unicode support. 

When you use #define _UNICODE at the top of your programs, these functions automatically switch from the char versions to the wchar_t versions for unicode support.


vedro-compota

ok. thank you guys ) I'll tre to understand it, but it'll be also possible to use more simple variant) = like this =int mainmenu(void)
{
   char ch; /* */
   char* mtext = " Please specify the number of the task. \n * You can choose on number from set = {1} \n * Specify \"0\" to exit\n" ;
   char* errmes = " Error(!) = Main menu does not support this command.\n Make sure that your task number is from menu set of commands and try again. " ;
   
   simple_read_all("input clearing", 5);
   printf("\n%s",mtext );
   ch = getchar();
   switch(ch)
   {
      case '0': exit(0); 
      case '1': exit(0); break; /*menu item - set yout function instead exit*/
      case '2': exit(0); break; /*menu item - set yout function instead exit*/
      case '3': exit(0); break; /*menu item - set yout function instead exit*/
      default: printf("\n%s\n", errmes);
   }
return 0;
}

about simple_read_all() read here = http://fkn.ktu10.com/?q=node/138

DMac

One thing to keep in mind about your function simple_read_all() is that whenever you use it you must capture the return value and free it when you are done with it.  Otherwise you will spring a memory leak.
It appears that you wish to use it, in this context, to flush the input, however, it does nothing of the sort.  To flush stdin you need to use fflush(), if you want to clear the console in windows you want to do the equivalent of typing cls at the prompt _tsystem(_T("cls")) or without generics system("cls").  In my console menu project I created the following macro to simplify this: #define Console_Clear() (fflush(stdin), _tsystem(_T("cls"))).
simple_read_all() was designed to read arbitrary lengths of text from stdin and return an allocated buffer.  This is good for a console based chat for instance, but not for what you want to do.  Don't use a tank to plow the garden just because you happen to have one in the village.
No one cares how much you know,
until they know how much you care.

CommonTater

Hi DMac...

Not to kick off a dispute here but... fflush(stdin); ... is generally considered a bad idea.  On many compilers it results in undefined behaviour that can be quite odd.  The Pelles C help file says the input buffers are cleared but defines this as non-standard behaviour. 

A better plan is something ike this...

while (getchar() != '\n');

Which will strip out everything to the next <Enter> in the buffer.

vedro-compota

fflush() works correctly....we're not interested in result (result value) in this case (as i understand)
CommonTater , your example needs some data in the input in the other case - the program will wait at least one symbol . in the same situation (when input was clear before some  cleaning call) fflush() won't stop the program - and it's good advantage)

CommonTater

#12
I guess you don't understand that fflush() works well enough *here*... but if you recompile with MinGW or GCC it may not (and in fact it doesn't)...

There are standards for these things, the standard does not define fflush() for inputs, stating the behavior is undefined.  "Undefined" means that you can't count on it in standards compliant coding... thus shouldn't use it.

the whole fflush(stdin) thing is a hangover from Borland's Turbo C... a 16 bit compiler that is 20 years out of date.

http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf

TimoVJL

#13
QuoteI guess you don't understand that fflush() works well enough *here*... but if you recompile with MinGW or GCC it may not (and in fact it doesn't)...
MinGW use msvcrt.dll ?
In windows fflush(stdin) is usable in most of compilers, but not in gcc/linux.

while (getchar() != '\n'); is used after ch = getchar();
ch = getchar();
while (getchar() != '\n');
May the source be with you

CommonTater

Quote from: timovjl on October 21, 2011, 05:35:20 PM
while (getchar() != '\n'); is used after ch = getchar();
ch = getchar();
while (getchar() != '\n');


yes, I should have been more explicit about that.... after getchar() and sometimes after scanf()...