CLI在C++:CIN和Ctrl + C
我有无限循环实现定制CLI,如下CLI在C++:CIN和Ctrl + C
while (1) {
getline(cin, _input);
_parse_cmd(_input);
}
我创建了一个信号处理程序如下:
BOOL WINAPI _consoleSignalHandler(DWORD CEvent) {
char mesg[128];
switch (CEvent)
{
case CTRL_SHUTDOWN_EVENT:
case CTRL_LOGOFF_EVENT:
case CTRL_CLOSE_EVENT:
case CTRL_BREAK_EVENT:
if (_CLI_instance) {
cout << "Close Signal" << endl;
}
break;
case CTRL_C_EVENT:
cout << "Ctrl + C to be implemented" << endl;
break;
default:
return FALSE;
break;
}
return TRUE;
}
利用这种配置,当我按CTRL + C时,CLI会打印消息"Ctrl + C to be implemented"
,并且不会再次等待用户输入。我该如何解决这个问题?
注:parse_cmd
是一个通用的命令分析器执行简单的行动
编辑:
你的问题是,在C++中,当getline
功能被中断,你下一步之前,需要手动清除错误状态呼叫。这足以在循环写:
while (1) {
getline(cin, _input);
if (cin.fail() || cin.eof()) {
cin.clear(); // reset cin state
}
_parse_cmd(_input);
}
但要注意:你还能过滤用CTRL-Break,你可以循环是很难阻止...
TL/DR:下面是我的第一个步骤首先在C语言中使用这个简单的解决方案,然后在C++中使用这种简单的解决方案,即只对Ctrl-C进行过滤并在Ctrl-Break上终止。
您可以轻松获得与signal
函数的Ctrl-C截取。
下面是使用的一个示例:
#include <stdio.h>
#include <signal.h>
void ctrl_c(int sig) {
fprintf(stderr, "Ctrl-C caught\n");
signal(sig, ctrl_c); /* re-installs handler */
}
int main() {
char buf[256];
void (*old)(int);
old = signal(SIGINT, ctrl_c); /* installs handler */
for (;;) {
if (fgets(buf, sizeof(buf), stdin) != NULL) {
printf("Got : %s", buf);
}
}
signal(SIGINT, old); /* restore initial handler */
return 0;
}
Ctrl-C键被截取,用CTRL-Break杀死该程序。
编辑:
旧的C版本很简单。在C++中,你必须明确标志在cin
如果getline
被打断:
#include <iostream>
#include <string>
#include <csignal>
using namespace std;
void ctrl_c(int sig) {
cerr << "Ctrl-C caught" << endl;
signal(sig, ctrl_c); // re-installs handler
}
int main() {
string buf;
void (*old)(int);
old = signal(SIGINT, ctrl_c); // installs handler
for (;;) {
getline(cin, buf);
if (cin.fail() || cin.eof()) {
cin.clear(); // reset cin state
}
else {
cout << "Got" << buf << endl;
}
}
signal(SIGINT, old); // restore initial handler
return 0;
}
这是正确的,现在C++,即使我不使用特定SetConsoleCtrlHandler
微软。恕我直言,信号使用如果更简单,如果只有Ctrl-C必须被捕获。
为什么你将OP的代码从C++更改为20世纪20年代的C? – 2014-11-05 17:36:04
@LightnessRacesinOrbit:因为我有这个我曾经使用的旧代码(很久很久以前......),我确信它的工作。但是你是对的,它没有回答OP问题:-(。谢谢你的评论。 – 2014-11-05 19:44:48
解决了它!谢谢:) – manatttta 2014-11-10 10:04:34
什么是_parse_cmd? – 2014-11-05 16:53:27
@MarcoA。这是一个简单的命令解析函数,只执行简单的动作 – manatttta 2014-11-05 16:57:01
为什么不禁用'ENABLE_PROCESSED_INPUT'模式,所以CTRL + C被报告为键盘输入而不是信号? – Sam12345 2014-11-05 17:27:02