Pelles C forum

C language => User contributions => Topic started by: DMac on July 14, 2011, 08:45:52 PM

Title: Simple console mode menu handling
Post by: DMac 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.
Title: Re: Simple console mode menu handling
Post by: CommonTater on July 15, 2011, 01:04:32 AM
VERY nice.... simple, effective and easily implemented.

Good work.
Title: Re: Simple console mode menu handling
Post by: Vortex on July 15, 2011, 07:48:53 PM
Hi DMac,

Nice work.
Title: Re: Simple console mode menu handling
Post by: grooves 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
Title: Re: Simple console mode menu handling
Post by: grooves 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
Title: Re: Simple console mode menu handling
Post by: 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. =
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...
Title: Re: Simple console mode menu handling
Post by: Stefan Pendl 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".
Title: Re: Simple console mode menu handling
Post by: CommonTater 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.

Title: Re: Simple console mode menu handling
Post by: vedro-compota 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  (http://fkn.ktu10.com/?q=node/138)
Title: Re: Simple console mode menu handling
Post by: DMac 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.
Title: Re: Simple console mode menu handling
Post by: CommonTater 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.
Title: Re: Simple console mode menu handling
Post by: vedro-compota 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)
Title: Re: Simple console mode menu handling
Post by: CommonTater 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
Title: Re: Simple console mode menu handling
Post by: TimoVJL 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');
Title: Re: Simple console mode menu handling
Post by: CommonTater 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()...
Title: Re: Simple console mode menu handling
Post by: vedro-compota on October 21, 2011, 05:41:47 PM
mmmm....i need clean input before getting the menu command so the code'll be =
Code: [Select]
while (getchar() != '\n');
 printf("\n%s",mtext );
   ch = getchar();
Title: Re: Simple console mode menu handling
Post by: CommonTater on October 21, 2011, 05:46:06 PM
You can do that... or you can do this...
Code: [Select]
printf("\n%s",mtext);
scanf(" %c", &ch);

Note the leading space between the " and % in the scanf() ... that tells it to ignore invisible characters (Enter, Tab, spaces, etc) hanging around in the buffer.


Title: Re: Simple console mode menu handling
Post by: vedro-compota on October 21, 2011, 06:13:24 PM
hm. the while (getchar() != '\n'); will stop program if the buffer is empty scanf() can get visible symbol from previous line which was put into input and hadn't been read at the whole - is there any way to check - is the buffer empty before call something which can make it so = http://forum.pellesc.de/index.php?topic=4052.0 (http://forum.pellesc.de/index.php?topic=4052.0)
Title: Re: Simple console mode menu handling
Post by: vedro-compota on October 21, 2011, 06:20:07 PM
CommonTater , in your previous post you've posted a link to book -is this c specification?
Title: Re: Simple console mode menu handling
Post by: CommonTater on October 21, 2011, 06:29:48 PM
CommonTater , in your previous post you've posted a link to book -is this c specification?

That is the current standard for C programming.

Title: Re: Simple console mode menu handling
Post by: EdPellesC99 on December 29, 2011, 01:00:12 AM
There seems to be a problem with downloading the attachment here, and for Timo's thread.

!! Maybe site work is in progress.... Ed
Title: Re: Simple console mode menu handling
Post by: Bitbeisser on December 29, 2011, 03:29:42 AM
There seems to be a problem with downloading the attachment here, and for Timo's thread.

!! Maybe site work is in progress.... Ed
Could be. Saw this happen in the tinyPDF thread to me yesterday, but all links that I tried today, just now, are working fine....

Ralf