NO

Author Topic: Simple console mode menu handling  (Read 16815 times)

Offline DMac

  • Member
  • *
  • Posts: 272
Simple console mode menu handling
« on: July 14, 2011, 08:45:52 PM »
Menu driven console applications couldn't be easier than with this simple menu handler.

This Code:
Code: [Select]
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:
Quote
Please 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

  • Guest
Re: Simple console mode menu handling
« Reply #1 on: July 15, 2011, 01:04:32 AM »
VERY nice.... simple, effective and easily implemented.

Good work.

Offline Vortex

  • Member
  • *
  • Posts: 797
    • http://www.vortex.masmcode.com
Re: Simple console mode menu handling
« Reply #2 on: July 15, 2011, 07:48:53 PM »
Hi DMac,

Nice work.
Code it... That's all...

grooves

  • Guest
Re: Simple console mode menu handling
« Reply #3 on: August 16, 2011, 05:30:29 PM »
Hi,

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

Thanks and regards,
grooves

grooves

  • Guest
Re: Simple console mode menu handling
« Reply #4 on: August 16, 2011, 05:32:14 PM »
sorry, I didn't found the Zip file,
and tried just the code snippet,

it works,
Thanks,
grooves

vedro-compota

  • Guest
Re: Simple console mode menu handling
« Reply #5 on: October 19, 2011, 06:47:11 PM »
well done) but there's a question - here's a code from your main() func. =
Code: [Select]
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...

Offline Stefan Pendl

  • Global Moderator
  • Member
  • *****
  • Posts: 582
    • Homepage
Re: Simple console mode menu handling
« Reply #6 on: October 19, 2011, 09:43:44 PM »
_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

  • Guest
Re: Simple console mode menu handling
« Reply #7 on: October 20, 2011, 02:43:02 AM »
well done) but there's a question - here's a code from your main() func. =
Code: [Select]
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

  • Guest
Re: Simple console mode menu handling
« Reply #8 on: October 20, 2011, 02:10:25 PM »
ok. thank you guys ) I'll tre to understand it, but it'll be also possible to use more simple variant) = like this =
Code: [Select]
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

Offline DMac

  • Member
  • *
  • Posts: 272
Re: Simple console mode menu handling
« Reply #9 on: October 20, 2011, 06:24:10 PM »
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

  • Guest
Re: Simple console mode menu handling
« Reply #10 on: October 21, 2011, 02:56:39 AM »
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...
Code: [Select]
while (getchar() != '\n');
Which will strip out everything to the next <Enter> in the buffer.

vedro-compota

  • Guest
Re: Simple console mode menu handling
« Reply #11 on: October 21, 2011, 03:25:12 PM »
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

  • Guest
Re: Simple console mode menu handling
« Reply #12 on: October 21, 2011, 05:21:40 PM »
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
« Last Edit: October 21, 2011, 05:32:12 PM by CommonTater »

Offline TimoVJL

  • Global Moderator
  • Member
  • *****
  • Posts: 2091
Re: Simple console mode menu handling
« Reply #13 on: October 21, 2011, 05:35:20 PM »
Quote
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)...
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();
Code: [Select]
ch = getchar();
while (getchar() != '\n');
« Last Edit: October 21, 2011, 05:43:20 PM by timovjl »
May the source be with you

CommonTater

  • Guest
Re: Simple console mode menu handling
« Reply #14 on: October 21, 2011, 05:37:26 PM »
while (getchar() != '\n'); is used after ch = getchar();
Code: [Select]
ch = getchar();
while (getchar() != '\n');

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