0

私はこのようなシグナルハンドラをプログラムしますか?

sig_quit(int signo)
{
    //char ans[5];
    char ans;

                printf("Are you sure want to exit program ?Y/N \n");
                //while(check){ check = !scanf("%s", ans); }

                //scanf("%c",&ans);
                ans=getchar();
                    //fgets(ans,sizeof(ans),stdin);;
                    printf("ans is : %c",ans);           
                    if(ans=='y' ||  ans=='Y')
                    {                                   
                        printf("Goodbye\n");
                        exit(0);
                        return;
                    }
                    else if(ans!='y')
                    {   

                        printf("why ans is : %c",ans);

                    }   
}

デフォルトの動作は、ctrl+\ を押すと、「終了してもよろしいですか?」という質問が表示されます。ユーザーが「y」を押すと終了しますが、ユーザーが「y」以外を押すと->scanf再びスタックしますが、ユーザーが「n」を押した後、関数を終了してメインに戻る必要がありますどうやって ?

簡単に言う@ getchar()scanf()、「y」を除く任意の文字を挿入した後、スタックした後、新しい入力を促し、スタックした後、ユーザーが新しい文字を挿入すると、シグナルハンドラー関数を終了して元に戻りますmain()

コードの新しいバージョンは次のとおりです。

したがって、これは最近のコードです:

volatile sig_atomic_t eflag = 0;
    int main(int argc, char *argv[])
    {

      /*Here are some code  ,,,,,, */

        Signal(SIGQUIT, sig_quit);  /* must call waitpid() */
         while (eflag) 
         {
            /* Main loop program code */

            log_msg(SIGQUIT);
         }



 ////// there is code below...
          .
          .
          .

    }
void log_msg(int signum)
{   
    char ans;
    //signal(SIGQUIT,SIG_IGN);  
            printf("Are you sure want to exit program ?Y/N \n");                        
        do  {
                ans=getchar();
                if(ans=='y' ||  ans=='Y')
                {                                   
                    printf("Goodbye\n");
                    exit(0);
                    return;
                }
                if(ans == 'n' || ans == 'N') return;

            }while(1);          
}


void
sig_quit(int signo)
{
    eflag = 1;
    /* Do some handling specific to SIGINT */
    log_msg(SIGQUIT);
}

それでも同じ問題 getchar() は、ユーザーが「n | | N」を押すと、再度任意の文字を押して main () に戻るまでブロックします。

4

3 に答える 3

2

C 標準によると、ほとんどのライブラリ関数をシグナル ハンドラで呼び出すと、未定義の動作が発生します。

実装は追加のサポートを提供できますが、既に IO を実行している関数を IO も実行するハンドラーで中断すると、予期しない動作が発生する可能性が高くなります。

これを行う「通常の」方法は、シグナル ハンドラーがグローバル変数を設定し、テストを配置しmainてそれが設定されていることを確認し、適切なアクションを実行することです。

于 2013-03-23T13:13:22.230 に答える
0

elseと 置き換えます

if(ans == 'n' || ans == 'N') break;  

編集

別の良い方法が存在するかどうかはわかりません:

int main(){  
char ans;  
printf('wanna exit?');  
do {  
ans = getchar();  
if(ans == 'y') exit(0);  
if(ans == 'n') break;  
}  
while(1);  
} 
于 2013-03-23T12:58:23.220 に答える
0

このコードを読んでもよろしいですか?もしそうなら、それを見栄えのするものにしてください。そうしないと、「うーん、読むのが大変。次へ!」と思うだけです...

シグナルハンドラは を返しvoidます。関数が返す型は、常にC で明示的に宣言する必要があります。ansは の戻り値を格納することを意図してgetchar()いるため、int.

void sig_quit(int sig) {
    int answer;
    do {
        puts("Are you sure you want to exit?");
        answer = getchar();
    } while (answer >= 0 && strchr("NnYy", answer) == NULL);

    if (strchr("Yy", answer)) { exit(0); }
}

「スタック」とは正確には何を意味しますか?完全に明確ではありませんが、実行をブロックする scanf および getchar の動作について言及していると思います。プログラムでデータがすぐに利用できない場合、データが利用可能になるまで待機し、その間に実行をブロックします。ユーザーがメインスレッドにデータを入力している間、バックグラウンドスレッドを実行して処理を続行することを検討しましたか?

于 2013-03-23T13:11:49.370 に答える