2013-10-09 37 views
1

當C.
這裏寫一個殼狀程序時,我曾經遇到過的信號處理問題是我的代碼的簡化版本:印刷錯誤使用信號處理程序

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <signal.h> 
#include <unistd.h> 
#define SIZE 255 

void sig_handler(int sig){ 
if (sig == SIGINT) 
    printf("\n[shell]$\n"); 
} 

int main() 
{ 
    char input[SIZE]; 
    printf("[shell]$"); 
    signal(SIGINT,sig_handler); 
    while(gets(input) != NULL){ 
    // code of the shell including command interpreter and command execution 
     printf("[shell]$"); 
    } 
    return 0; 
} 

當我運行該程序,嘗試與命令信號情報 - 「貓」時,輸出表示爲以下:

[shell]$ ^C (ctrl+C pressed for the first time) 
[shell]$  
^C   (the input position go to the next line, which is unwanted) 
[shell]$ 
cat   (I want it in the same line with [shell]$) 
^C 
[shell]$ 
[shell]$  (duplicate printing occurs) 

我試圖通過刪除第二\ n至修改函數void sig_handler(INT SIG)。然而,情況比以前變得更糟。程序在第一次按下ctrl + C時不會自動觸發信號事件。

爲了澄清我的問題,這裏是我問的兩個問題:
1.如何使輸入位置與[shell] $在同一行上?
2.如何解決重複打印問題?

+1

不確定重複的東西,但是可以通過在打印的字符串的末尾刪除\ n來打印同一行上的內容(儘管您可能需要使用fflush(stdout)使其顯示) 。 – zneak

+0

非常感謝!對於細微的問題,我已經通過創建另一個沒有printf的信號處理函數來解決它。 –

回答

1

說什麼@zneak是真實的,你可以使用fflush和刪除sig_handler第二\n

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <signal.h> 
#include <unistd.h> 
#define SIZE 255 

void sig_handler(int sig){ 
if (sig == SIGINT) 
    printf("\n[shell]$"); 
    fflush(stdout); 
} 

int main() 
{ 
    char input[SIZE]; 
    printf("[shell]$"); 
    fflush(stdout); 
    signal(SIGINT,sig_handler); 
    while(gets(input) != NULL){ 
    // code of the shell including command interpreter and command execution 
     printf("[shell]$"); 
    } 
    return 0; 
} 
+0

非常感謝!我的程序按我現在的想法工作。 –

0

首先,從信號處理印刷是一種壞主意。信號處理器就像一箇中斷處理程序 - 它是異步發生的,它可以在標準庫代碼中引發,調用另一個stdlib子程序時可能會遇到非重入內部事件(想象一下在你的循環中在printf()內部捕獲SIGINT) 。

如果您確實想從內部輸出某些內容,則最好使用生成的write()調用stderr文件描述符。