1

このプログラム

#include <stdio.h> 
#include <signal.h>
#include <stdlib.h>
#include <windows.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>

void INThandler(int);             

int  main(void)
{
   signal(SIGINT, INThandler);    

   char data[128];

   int n;

   while((n=read(0, data, 128)) > 0)
   {
   if(data[n] = '\n') break;
   }

   data[n] ='\0';

   printf("%s", data);

   return 0;
}

void  INThandler(int sig)
{
     char  c;

     signal(sig, SIG_IGN);             
     printf("OUCH, did you hit Ctrl-C?\n"    
            "Do you really want to quit? [y/n] ");
     c = getchar();                     
     if (c == 'y' || c == 'Y')          
         exit(0);                      
     else
      signal(SIGINT, INThandler);
}

ctrl-c を処理しませんが、その入力で終了します。ハンドラーのインストールと戻りの間のすべてを置き換えると

while (1)                          
Sleep(1);

ハンドラー関数が呼び出されて機能しますが、そこに read() を入れたいです。

編集: このプログラムを振り返ってみると、

if(data[n] = '\n') break;

「==」ではなく「=」と書いたのですが、後者を使うとうまく動作せず理由がわかりません。「\n」を検出するための比較ではないでしょうか。また、バッファをいじりましたが、CTRL-C を押しても入力をキープできません。

4

2 に答える 2

1

サンプル コードでは、次の 2 つの問題が考慮されていません。

  1. read()プロセスがシグナルを受信すると、その作業を中止します (「 」を参照man 2 read)
  2. 一部の関数については、シグナル ハンドラ関数から安全に呼び出せることが保証されているだけです (「参考文献」を参照man 7 signal)。printf()この一連の「保存」機能には属しgetch()ません。

最初の問題は、 によって返される値を処理するためのより差別化された方法を使用して修正できますread()。に渡されたバッファのスマートな調整とともに、既に読み取られたデータの量をカウントする必要がありますread()

2番目の問題に関しては、上記のマンページで「保存」機能としてリストされread()write()いるため、シグナルハンドラーへの/からの入出力を実行するために選択される機能です。

于 2013-03-07T15:51:49.287 に答える
0

これは、read(2)使用の実装が許可されていないためです。プログラムをコンパイルして実行し、^C を押すと、次のようになります。

$ ./program
^COUCH, did you hit Ctrl-C?
Do you really want to quit? [y/n] y
$

または、n と答えてデータを入力すると、次のようになります。

$ ./program
^COUCH, did you hit Ctrl-C?
Do you really want to quit? [y/n] n
test
test
$

はシステムコールなのでread(2)、使用するシステムに依存します。私は Linux (3.2.0-4-686-pae) を使用していますが、ここでは正しく動作しています。使用しているプラ​​ットフォームに対して、代わりにscanf(3)or fread(3)withを使用することを検討する必要があるかもしれません(これはwin32と見なされます)。または、 CygwinMinGWのような別の実装を使用しますか?stdio(3)

于 2013-03-06T13:28:48.820 に答える