如何在C++程序中实现ESC按键退出功能并解决相关编译警告
Hey there! Let's fix up your tollbooth program step by step—first squashing those annoying compile warnings, then getting that ESC key working properly.
First: Fix the Compile Warnings
Your two warnings are both caused by the same line: char ESC = '27';
- Multi-character character constant: Single quotes (
' ') are meant for single characters only. Writing'27'tries to cram two characters into a singlecharvariable, which is invalid. - Overflow in implicit conversion: The multi-character constant
'27'has a numerical value way outside the range of a standard 1-bytechar(-128 to 127), leading to an overflow when assigning it.
The fix is simple: ESC's ASCII value is 27, so define it directly as the numerical value or using an escape sequence:
const char ESC = 27; // OR equivalently: const char ESC = '\033'; (octal escape for ASCII 27)
Second: Make the ESC Key Actually Work
The root problem with your current setup is cin>>ch: it uses line-buffered input, meaning it waits for you to press Enter before reading anything. Also, the ESC key doesn't register as a printable character that cin can capture this way.
To read keys directly (without waiting for Enter), we need to use a non-standard input function tailored to your OS:
For Windows
Use the _getch() function from the <conio.h> header—it reads a key press immediately without requiring Enter.
For Linux/macOS
The <conio.h> header doesn't exist natively, so we can create a custom getch() function using terminal control calls to mimic the Windows behavior.
Full Fixed Code (Windows Version)
#include<iostream> #include<string> #include<conio.h> // Required for _getch() on Windows using namespace std; class tollbooth{ private: unsigned int TotalCars; double TotalCash; public: tollbooth() { TotalCars = 0; TotalCash = 0; } void payingCar() { TotalCars += 1; TotalCash += 0.50; } void nopayCar() { TotalCars += 1; } void display() { cout<<"Total cars Passed: "<<TotalCars<<endl<<"Total Cash collected by cars: "<<"$"<<TotalCash<<endl; } }; int main() { tollbooth t1; const char ESC = 27; // Fixed: Use ASCII value for ESC char ch; cout << "输入0代表一辆未缴费车辆" << endl; cout << "输入1代表一辆已缴费车辆" << endl; cout << "按下ESC键退出" << endl; do{ ch = _getch(); // Read key press immediately, no Enter needed if(ch == '0') { t1.nopayCar(); cout << "已记录一辆未缴费车辆" << endl; // Optional: Give user feedback } if(ch == '1') { t1.payingCar(); cout << "已记录一辆已缴费车辆" << endl; // Optional: Give user feedback } } while(ch != ESC); t1.display(); return 0; }
Full Fixed Code (Linux/macOS Version)
Add a custom getch() function to bypass line buffering:
#include<iostream> #include<string> #include<termios.h> #include<unistd.h> using namespace std; // Custom getch() to read keys without Enter on Linux/macOS char getch() { char buf = 0; struct termios old_term = {0}; if (tcgetattr(0, &old_term) < 0) perror("tcsetattr() failed"); // Disable line buffering and echo old_term.c_lflag &= ~ICANON; old_term.c_lflag &= ~ECHO; old_term.c_cc[VMIN] = 1; old_term.c_cc[VTIME] = 0; if (tcsetattr(0, TCSANOW, &old_term) < 0) perror("tcsetattr ICANON failed"); read(0, &buf, 1); // Restore terminal settings old_term.c_lflag |= ICANON; old_term.c_lflag |= ECHO; if (tcsetattr(0, TCSADRAIN, &old_term) < 0) perror("tcsetattr ~ICANON failed"); return buf; } class tollbooth{ // Same tollbooth class as before... private: unsigned int TotalCars; double TotalCash; public: tollbooth() { TotalCars = 0; TotalCash = 0; } void payingCar() { TotalCars += 1; TotalCash += 0.50; } void nopayCar() { TotalCars += 1; } void display() { cout<<"Total cars Passed: "<<TotalCars<<endl<<"Total Cash collected by cars: "<<"$"<<TotalCash<<endl; } }; int main() { tollbooth t1; const char ESC = 27; char ch; cout << "输入0代表一辆未缴费车辆" << endl; cout << "输入1代表一辆已缴费车辆" << endl; cout << "按下ESC键退出" << endl; do{ ch = getch(); // Use our custom getch() if(ch == '0') { t1.nopayCar(); cout << "已记录一辆未缴费车辆" << endl; } if(ch == '1') { t1.payingCar(); cout << "已记录一辆已缴费车辆" << endl; } } while(ch != ESC); t1.display(); return 0; }
What Changed?
- Fixed the ESC constant definition to eliminate compile warnings.
- Replaced
cin>>chwith direct key-reading functions to capture the ESC press without needing Enter. - Added optional user feedback so you know your input was registered.
内容的提问来源于stack exchange,提问作者Muzamil Farooque

