2014-11-05 92 views
1

我有無限循環實現定製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是一個通用的命令分析器執行簡單的行動

+0

什麼是_parse_cmd? – 2014-11-05 16:53:27

+0

@MarcoA。這是一個簡單的命令解析函數,只執行簡單的動作 – manatttta 2014-11-05 16:57:01

+0

爲什麼不禁用'ENABLE_PROCESSED_INPUT'模式,所以CTRL + C被報告爲鍵盤輸入而不是信號? – Sam12345 2014-11-05 17:27:02

回答

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-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必須被捕獲。

+2

爲什麼你將OP的代碼從C++更改爲20世紀20年代的C? – 2014-11-05 17:36:04

+0

@LightnessRacesinOrbit:因爲我有這個我曾經使用的舊代碼(很久很久以前......),我確信它的工作。但是你是對的,它沒有回答OP問題:-(。謝謝你的評論。 – 2014-11-05 19:44:48

+0

解決了它!謝謝:) – manatttta 2014-11-10 10:04:34