2016-06-28 69 views
0

我必須在while循環中從用戶處獲得輸入,然後採取一些措施。而且我也想在ctrl + c輸入中退出我的代碼。使用scanf循環處理SIGINT

void my_signal_handler(int sig) 
{ 
    running = false; 
    signal(sig, SIG_IGN); 
} 
int main(void) 
{ 
    struct sigaction sa = {{0}}; 
    sa.sa_handler = &my_signal_handler; 
    sigemptyset(&sa.sa_mask); 
    sa.sa_flags = 0; 

    if (sigaction(SIGINT, &sa, NULL) != 0) 
    { 
     fprintf(stderr, "sigaction error\n"); 
     return -1; 
    } 
    while(running) 
    { 
     printf("enter number: "); 
     scanf("%d", &num); 
     // take action based on number 
    } 
} 

問題的這個代碼是按CTRL + C,它不退出之後,但它等待針對scanf的輸入。所以一旦我按下一個額外的鍵,程序就會退出(信號處理程序被調用)。

如何在按下ctrl + c後刪除這個給scanf輸入的額外步驟?

+0

你可以通過激勵來改善你的問題嗎(所以請**編輯你的問題**)? –

+0

順便說一下,給定的代碼不會編譯。 'scanf(%d「中有一個雙引號缺失,&num);' –

回答

1

您應該安裝信號處理程序。最起碼,加

signal(SIGINT, my_signal_handler); 

裏面你mainwhile(running),而是更好地利用sigaction(2)前。

你也應該知道stdiobuffering;通常stdout在終端時是線路緩衝的(但請參閱setvbuf(3)和朋友)。因此,您應該在循環內的scanf之前呼叫fflush(3)(可能爲fflush(NULL);),或者以明確的\n終止每個printf格式控制字符串。

最後,scanf(3)可能會失敗並返回您應該測試的掃描項目的計數。

順便說一句,您的main是錯誤的,應該定義爲int main(void)或最好是int main(int argc, char**argv)

但是(假設你是在Linux上),讀得很仔細​​(注意什麼說一下信號處理程序和異步信號安全功能)和POSIX signal.h documentation並宣佈你running標誌作爲

volatile sigatomic_t running; 

(或也許在C11中,如volatile _Atomic bool running;

volatile qualifier非常重要。否則,允許編譯器優化(並假設running總是爲真)。

請注意,使用signal(2)通常是一個壞主意。首先,如果你真的需要信號處理,你最好使用sigaction(2)。那麼你的電話signal(sig, SIG_IGN);,在你的情況下,是無用的(因爲running揮發性標誌將在信號處理程序中更改)。最後,對於多路複用輸入(&輸出),您可以使用poll(2),它可用於等待並測試stdin(實際上STDIN_FILENO是0)是否存在某些可用輸入,並且更一般地用於執行event loops。您可以使用(而不是poll,我強烈建議)舊的和幾乎過時的select(2),但您寧可使用poll(2)。另請參閱epoll(7) & inotify(7)但您可能不需要它們。

請注意,在終端,stdin往往是繼line discipline一個TTY(檢查與isatty(3))(所以一些行緩衝的情況內核)。閱讀tty demystified頁面。考慮使用GNU readline庫和函數(或者可能是ncurses),這可能是你真正需要的。

另請參閱Advanced Linux Programming並養成閱讀您正在使用的每個函數的文檔的習慣。

+0

實際上,在行信號處理程序配置中,我已經爲sigaction添加了適當的代碼,我將再次更新代碼以顯示我的actual_code。 – Patrick

+0

@BS你可以顯示這一行的代碼示例「多路複用輸入(&輸出),你可以使用poll(2),它可以用來等待和測試stdin上是否有一些可用的輸入(實際上是STDIN_FILENO,它是0)。」 – Patrick

+0

這可能需要我太多時間(特別是如果你對Linux編程不太熟悉),我提供了參考資料,特別是ALP書籍 –