473,756 Members | 7,560 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Creating a menu system with standard C functions

Hi all!
I wrote the following as a test case for a menu based programme:

#include <iostream>
#include <cstring>
using namespace std;

#define cls system("cls")

const int SIZE = 10;
int numbers[SIZE];

void list() {
cls;
cout << "List" << endl << endl;
for(int i=0; i<SIZE; i++) {
cout << i << endl;
}

getchar(); // Doesn't work!
cls;
mainMenu();
}

void add() {};

void remove() {};

int mainMenu() {
char c;
do {
cout << "Main menu" << endl << endl;

cout << "(L)ist" << endl
<< "(A)dd" << endl
<< "(R)emove" << endl << endl
<< "(Q)uit" << endl << endl
<< "Selection: ";

cin >c;
switch(c) {
case 'l': ; // Fallthrough to uppercase L
case 'L': list(); break;
case 'a': add(); break;
case 'r': remove(); break;
case 'q': break;
}
} while(c!='q');

return 0;
}

int main() {
// Init numbers
memset(numbers, 0, sizeof(int)*SIZ E-1);
mainMenu();

return 0;
}

Why isn't the programme pausing and waiting for a RETURN key press
after listing the contents of numbers in the function list()?

Many thanks in advance,
Philipp
Nov 22 '07 #1
4 3018
Hi,

What you are having is a classic getchar() problem for interactive use.

try to run the following example code

#include <iostream>
int main(void) {
std::cout << "test getchar()" << std::endl;
getchar();
std::cout << "test cin" << std::endl;
char c;
std::cin >c;
std::cout << "test getchar() again" << std::endl;
getchar();
return 0;
}

The first time you type 'a' when it pauses followed by ENTER
Then when it pauses type 'b' again followed by enter.
You will notice that the second getchar() command is not pausing.

[]$ ./a.out
test getchar()
a
test cin
b
test getchar() again
[]$

Run it again and type at the first time when it pauses, abc followed by
ENTER. The two next pauses will fail.

[]$ ./a.out
test getchar()
abc
test cin
test getchar() again
[]$

So the problem is the following.

Normally, getchar() is implemented in such a way that it buffers input
until ENTER is pressed. This is called line-buffered input. You have
to press ENTER before anything you typed is actually sent to the
program. Also since getchar() inputs only one character each time it is
called, line-buffering may leave one or more characters waiting in the
input queue, which is annoying in interactive environments like you want
here. Even though Standard C/C++ specifies that getchar() can be
implemented as an interactive function, it seldom is. Therefore it does
not work.

So in the above first run we had the following.
[]$ ./a.out
test getchar()
a << ENTER > // buffer contains "a,ENTER"
// getchar() reads 'a', buffer contains "ENTER"
test cin // cin ignores ENTER and waits for real input,
// buffer empty
b << ENTER > // buffer contains "b,ENTER"
// cin reads 'b', buffer contains "ENTER"
test getchar() again
// getchar() sees ENTER in buffer and uses it, no
// pause!
[]$

In the second test the first buffer contains "a,b,c,ENTE R". getchar()
reads a, cin reads b and still the buffer contains "c,ENTER", hence
getchar() takes the 'c' and the programs exits without any pause.

The problem you have is that you call first cin and then getchar() with
the "ENTER" left in the buffer. so what you need to do is empty your
buffer. This can be done in the following way in your code

int mainMenu() {
char c[10]; // CHANGE THIS
do {
cout << "Main menu" << endl << endl;

cout << "(L)ist" << endl
<< "(A)dd" << endl
<< "(R)emove" << endl << endl
<< "(Q)uit" << endl << endl
<< "Selection: ";

cin >c; // READS THE TYPED WORDS BUT LEAVES
// ENTER IN BUFFER,
// hope you don't type more then 10 chars
getchar(); // REMOVES THE ENTER
switch(c[0]) { // ALTER THIS
case 'l': ; // Fallthrough to uppercase L
case 'L': list(); break;
case 'a': add(); break;
case 'r': remove(); break;
case 'q': break;
}
} while(c[0]!='q'); // ALTER THIS

return 0;
}
When you did this, the use of getchar() in your list function will work,
but only with the use of the "ENTER" keystroke.
If you press at that time any other key and then followed by ENTER your
buffer is full again, and you will have a problem with the next cin in
mainmenu.

The best would be again to change that getchar() in your list function by

char c[10];
std::cin >c;
getchar();

If you did this, your program will work as expected ... at least i think :p

Enjoy and regards
ps take a look at
http://www.parashift.com/c++-faq-lit...html#faq-15.17
Nov 22 '07 #2
Thanks a million for this very detailed explanation.
Because I am the only user of this programme I can be sure that the
user knows not to type more than one char at a time. So I just call
getchar() twice to have the desired effect.

BTW: What's so ironic about my situation is that I'm forced to use gcc
3.4 under Windows (involving cmd.exe), but to assure it'll run under
Sun Solaris with gcc 4.1.1 and bash.
Altough this is off-topic now, is there any portable solution to this?

On 22 Nov., 18:10, ciccio <no_valid_em... @spam.comwrote:
Hi,

What you are having is a classic getchar() problem for interactive use.

try to run the following example code

#include <iostream>
int main(void) {
std::cout << "test getchar()" << std::endl;
getchar();
std::cout << "test cin" << std::endl;
char c;
std::cin >c;
std::cout << "test getchar() again" << std::endl;
getchar();
return 0;

}

The first time you type 'a' when it pauses followed by ENTER
Then when it pauses type 'b' again followed by enter.
You will notice that the second getchar() command is not pausing.

[]$ ./a.out
test getchar()
a
test cin
b
test getchar() again
[]$

Run it again and type at the first time when it pauses, abc followed by
ENTER. The two next pauses will fail.

[]$ ./a.out
test getchar()
abc
test cin
test getchar() again
[]$

So the problem is the following.

Normally, getchar() is implemented in such a way that it buffers input
until ENTER is pressed. This is called line-buffered input. You have
to press ENTER before anything you typed is actually sent to the
program. Also since getchar() inputs only one character each time it is
called, line-buffering may leave one or more characters waiting in the
input queue, which is annoying in interactive environments like you want
here. Even though Standard C/C++ specifies that getchar() can be
implemented as an interactive function, it seldom is. Therefore it does
not work.

So in the above first run we had the following.

[]$ ./a.out
test getchar()
a << ENTER > // buffer contains "a,ENTER"
// getchar() reads 'a', buffer contains "ENTER"
test cin // cin ignores ENTER and waits for real input,
// buffer empty
b << ENTER > // buffer contains "b,ENTER"
// cin reads 'b', buffer contains "ENTER"
test getchar() again
// getchar() sees ENTER in buffer and uses it, no
// pause!
[]$

In the second test the first buffer contains "a,b,c,ENTE R". getchar()
reads a, cin reads b and still the buffer contains "c,ENTER", hence
getchar() takes the 'c' and the programs exits without any pause.

The problem you have is that you call first cin and then getchar() with
the "ENTER" left in the buffer. so what you need to do is empty your
buffer. This can be done in the following way in your code

int mainMenu() {
char c[10]; // CHANGE THIS
do {
cout << "Mainmenu" << endl << endl;

cout << "(L)ist" << endl
<< "(A)dd" << endl
<< "(R)emove" << endl << endl
<< "(Q)uit" << endl << endl
<< "Selection: ";

cin >c; // READS THE TYPED WORDS BUT LEAVES
// ENTER IN BUFFER,
// hope you don't type more then 10 chars
getchar(); // REMOVES THE ENTER
switch(c[0]) { // ALTER THIS
case 'l': ; // Fallthrough to uppercase L
case 'L': list(); break;
case 'a': add(); break;
case 'r': remove(); break;
case 'q': break;
}
} while(c[0]!='q'); // ALTER THIS

return 0;

}

When you did this, the use of getchar() in your list function will work,
but only with the use of the "ENTER" keystroke.
If you press at that time any other key and then followed by ENTER your
buffer is full again, and you will have a problem with the next cin in
mainmenu.

The best would be again to change that getchar() in your list function by

char c[10];
std::cin >c;
getchar();

If you did this, your program will work as expected ... at least i think :p

Enjoy and regards

ps take a look athttp://www.parashift.c om/c++-faq-lite/input-output.html#faq-15.17
Nov 24 '07 #3
<Ph************ *******@gmail.c omwrote in message
news:44******** *************** ***********@l1g 2000hsa.googleg roups.com...
Hi all!
I wrote the following as a test case for a menu based programme:
<snip>
>
Why isn't the programme pausing and waiting for a RETURN key press
after listing the contents of numbers in the function list()?

Many thanks in advance,
Philipp
I reckon that 'cin>>c' does not remove the carriage return from
the input stream. When getchar( ) is called later, it immediately retrieves
the carriage
return that was waiting there.

HTH
Stéphane Perras
Nov 24 '07 #4
Ph************* ******@gmail.co m wrote:
Thanks a million for this very detailed explanation.
Because I am the only user of this programme I can be sure that the
user knows not to type more than one char at a time. So I just call
getchar() twice to have the desired effect.

BTW: What's so ironic about my situation is that I'm forced to use gcc
3.4 under Windows (involving cmd.exe), but to assure it'll run under
Sun Solaris with gcc 4.1.1 and bash.
Altough this is off-topic now, is there any portable solution to this?
Could you elaborate a bit on this? What is actually the thing you want?
Using the same executable, the same source, you don't want to use
commandline?
Nov 26 '07 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
2124
by: Richard Hollenbeck | last post by:
Back in the old days before I started learning about menubars (the day before yesterday,) I based all my operations on command buttons on the forms. Now the forms are all cluttered up with buttons so I'm beginning to clean it up using menubars. So far, I haven't used ANY macros. But some some websites, as well as my book, seems to indicate that it is necessary to base the menubar on a macro with each menu's first instruction being...
5
3546
by: markus | last post by:
Hi, I have a question that deals with the standard c library VS (Unix) system calls. The question is: which header files (and functions) are part of the C library and which header files (and function calls) are part of the (Unix) system calls. The cause of my confusion is that for example stdio.h is considered
8
10101
by: Dennis C. Drumm | last post by:
Is there a way to modify the standard context menu shown when someone right clicks in a windows text box and that would work for all open windows applications? The standard context menu for a text box has 6 items, undo, cut, copy, paste, delete and select all. I would like to add one additional paste menu that opens a new sub menu with several optional text items that could be pasted. The items would be populated by my program but...
5
2284
by: lgbjr | last post by:
Hello All, I have several Pictureboxes (linked to an AccessDB) on a VB.NET form. I would like to use a context menu to allow the user to open the picture in their default picture viewer or editor. I'd like to use the same default viewer/editor and open with... choices that are present on the users computer. Does anyone know how I can find this information programatically, so my picturebox context menu uses the same settings as the...
1
6341
by: goRide | last post by:
Hi, I'm looking of a way (preferred - a ready class or dll) to customize the context menu. many application has more controls inside the context menu (like textbox, sliders, checkbox, panel etc'). is there a way making this without writing my own context menu (meaning, popup form or something) ? Please don't post commercial products to this topic thanks.
27
45564
by: Wayne | last post by:
I've been clicking around Access 2007 Beta 2 and can't see the custom menu bar designer. Is it in the beta? Maybe I'm blind. The question that comes to mind is: Will custom menu bars be the same height as they were in previous versions or will they be the "ribbon" style that takes up a huge portion of the screen? Also when I use Access 2007 to open an Access 2003 database that has custom menu bars they display as they did in Access...
2
5555
by: Sebouh | last post by:
Hi all. I'm not sure if this is the right place to ask, but here it goes. I'm trying to create a file system using the File System in User Space (FUSE) kernel module. From what i have understood, i need to implement certain functions, like the read, write, and delete that should be referenced by the fuse_main function. Now whenever my program uses the standard C functions, it references the functions i created to manipulate the file in my file...
5
6344
by: tech.rawsteak | last post by:
I have a function that retrieves a user's login name from their workstation and looks it up on an employee table to return their full name (ie: jsmith -John Smith). Their full name is then displayed on each form as a greeting, while their login name is used to record their activities, as well as compared to a list of positions that allows different users to access different functions on the database. I have noticed two things however: ...
1
2518
by: Kayvine | last post by:
Hi guys, this is a question I have for an assignment, it is pretty long, but I am not asking for the code(well if someone wants to write I'll be really happy, lol), but I just want to know how to start it and what main topics in C I will need to cover in the assignment. Thanks a lot. CSC180 Assignment #3: Menu Madness Due Date: Thursday, November 8th at 1:00am Contents: · General Info · What to Hand In o Submission Instructions
0
9456
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9275
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10040
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
9846
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9713
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
7248
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6534
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5142
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
2
3359
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.