cancel input operation without terminating console

Can anyone please give me some hint on how can I terminate an input session in a console app without terminating console/closing app? Consider this scenario at console, If the user is asked to input multiple line, the only way out would be to finish with all inputs or Ctrl + C to terminate the console. But I want to let user Press e.g. F9 to end this operation without making input, and then going back to previous page. Is that possible?

Please Enter Student Detail:

First Name:
Last Name:
.
.
.
.
.
Address:
What os are you using?

One way would be to have say a '.' as a break char and if this is entered then break from a loop etc etc. For non-os specific, you'll need to enter '.' and then a \n.

There are os specific ways of obtaining a char without also having to enter \n.
os is Windows
You can use _getch() in #include <conio.h>

This will get one char from the keyboard without waiting for a \n to be entered. Say the ESC key is the key to press to end the operation (easier to use then a function key). Instead of using getline() to obtain a line of input, you can use something like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <string>
#include <iostream>
#include <conio.h>

bool getInp(std::string& line)
{
	auto ch {static_cast<unsigned char>(_getch())};

	// ESC (27) as terminate char
	if (ch == 27)
		return true;

	// Check for F9
	if (ch == 0)
		if (ch = static_cast<unsigned char>(_getch()); ch == 'C')
			return true;
		else
			ch = 0;

	if (ch)
		std::cout << ch;

	std::getline(std::cin, line);

	if (ch)
		line.insert(0, 1, static_cast<char>(ch));

	return false;
}

int main()
{
	std::cout << "Enter data (ESC or F9 to terminate): ";

	std::string line;

	if (const auto term {getInp(line)}; term)
		std::cout << "\nTerminated\n";
	else
		std::cout << line << '\n';
}


This will display 'Terminated' if either ESC or F9 keys are pressed, otherwise displays what was entered.

Note that keys such as F9 produce 2 chars - first one is 0 and a second depending upon the key. F9 is C, f8 is B etc. If you want to use function keys like this, then you'll need to find out what chars are produced for what key combinations. Some special keys first produce 0xE0 (224) first.

Have fun!
Last edited on
Ingenious! It's perfect and thank you for extra explanation :)
Last edited on
Hello hdcpp64,

In MSVS 2017 using Windows I use this:

1
2
3
4
5
6
7
    // <--- Keeps console window open when running in debug mode on Visual Studio. Or a good way to pause the program.
    // The next line may not be needed. If you have to press enter to see the prompt it is not needed.
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');  // <--- Requires header file <limits>.
    std::cout << "\n\n Press Enter to continue: ";
    std::cin.get();

    return 0;  // <--- Not required, but makes a good break point. 

You could also make use of line 3 by its-self as a way to pause the program, but that would require a clear input buffer to start with.

See Also http://www.cplusplus.com/forum/beginner/1988/

Andy
Andy, what's your post got to do with the OP's requirement??
Thanks Andy, though my situation is more complicated (or its simple and I haven't worked it out yet)!

@seeplus
Although your solution for exiting an input prompt works, but it either can not be applied in my case or I haven't been able to implement it properly. In sample code below, I have setFname(), setIdnum() and many other set functions which include while loop for checking the right entry (for example certain length and characters for ID or Phone format or...). And then as you see, I use them inside other loops for entry, verify and database insertion.

How can I break out of such condition? Because once user is prompted for lets say Idnum, it is directed to accept only certain characters and length, if not an error, and then keep asking for Idnum. Same goes to all other set functions.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
void myClass::studentEntry(){
	
	char con;
	do {
			
			ClearScr();
			std::cout << "\n\tPlease Enter Student Information:\n";
			
			obj.setFname();
			obj.setIdnum();
			.
			.
			.
			.
			obj.setAddress();
			do
			{
				ClearScr();
				std::cout << "\n\tPlease Confirm Student Information:\n\n";
				std::cout << "\tFull Name: " << obj.getFname() << std::endl;
				std::cout << "\tId Number: " << obj.getIdnum() << std::endl;
				.
				.
				.
				.
				.
				std::cout << "\tAddress: " << obj.getAddress() << std::endl;
				
                                 con=obj.getConfirm(); //if Y go for database insertion, if N, restart entry

				if(con=='Y')
				{
				
						//LONG PROCEDURE OF INSERTING INTO SQL DATABASE.
				
				}
				else if (con == 'N')
				{
						std::cout << "\tNothing Saved into Database!";
						break;
				}
			
					
			}
			while(con=='N');
	}
	while(con=='N');

};
Last edited on
What you want is non-trivial to implement - it's almost like going back to the days of ms-dos/mini/mainframe programming of the 1980's (oh happy days)!

Because once user is prompted for lets say Idnum, it is directed to accept only certain characters and length, if not an error, and then keep asking for Idnum. Same goes to all other set functions.


What you need to do is to change .setIdnum() to use getInp() (or similar) from above to obtain keyboard input. .setIdum() also needs to return bool. Within .setIdum() after you use getInp() and the return value is true then .setIdnum() returns true. Otherwise parse the input from getInp() and return false when OK.

Where .setIdnum() is used, you need to test the return value and if true then break out of the loop (or other processing as required).

The same goes for all the other functions that obtain input!
Last edited on
@seeplus
You are right! it's meaningless. well that's what happens when one keep expanding on a small console app for school project. I should skip on adding to this console app and better to switch to an actual or Non-Trivial app ;)
Last edited on
I should skip on adding to this console app and better to switch to an actual or Non-Trivial app


Probably, yes. Now-a-days, no one writes console programs (unless as a specific console command). Everything is gui. The only reason that the console features so heavily when learning C++ is that standard C++ only uses the console for interactive input/output - it doesn't have in-built gui capabilities. This capability has to be provided by 3rd party libraries. Other languages eg. java (with swing), c#, vb.net et al do provide gui capabilities so for these languages gui is taught from the beginning. This can't currently be done with C++ - hence the heavy use of the console. There are various gui libraries available for C++ . Some (such as QT) are x-platform. Some are specific MS etc.

If you want to try some gui programming, then the book Programming: Principles and Practice Using C++ by Bjarne Stroustrup (inventor of C++) uses FLTK and provides guidance and examples of how to install and use.

Topic archived. No new replies allowed.