C ++中的CLI:cin和Ctrl + C

问题描述 投票:1回答:1

我有一个无限循环来实现自定义CLI,如下所示

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++ windows command-line-interface
1个回答
1
投票

编辑:

[您的问题是,在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-< [中断。

您可以通过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; }

即使我不使用Microsoft特定的SetConsoleCtrlHandler,它现在也是正确的C ++。如果仅需捕获[[Ctrl
-

C,则IMHO信号的使用更为简单。

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.