0

ボタン付きのシンプルなココア アプリを作成しました。

ボタンをクリックすると、タイマーがトリガーされます。

[NSTimer scheduledTimerWithTimeInterval:1.0f 
                                 target:self 
                               selector:@selector(readCommandResult:)
                               userInfo:nil
                                repeats:YES];

そして、ここにタイマーがあります:

-(void)readCommandResult:(NSTimer *) timer
{
char ps_cmd[256] = {"ls"};
BOOL isFgetsOK = NO;

FILE *fp = popen(ps_cmd, "r"); 
if (fp) {
    char line[4096];
    while (line == fgets(line, 4096, fp)) {

        isFgetsOK = YES;
    }
    pclose(fp);
}
else {

    NSLog(@"popen error");
}   
if (!isFgetsOK) {
    NSLog(@"fgets error");
}
}

アプリを実行すると、「fgets エラー」が発生することがあります。「line == fgets(line, 4096, fp))」が失敗したように見えますが、理由はわかりません。

ここで時々ランダムに「fgetsエラー」が発生する理由を説明してもらえますか??

PS: コマンドを ("ls" から "ps" に) 変更しようとしました。ターミナルで、次の結果が得られました。

  PID TTY           TIME CMD
  744 ttys000    0:00.02 -bash

そして、タイマーの新しいコード:

 -(void)readCommandResult:(NSTimer *) timer
    {
    char ps_cmd[256] = {"ps"};
    BOOL isFgetsOK = NO;

    FILE *fp = popen(ps_cmd, "r"); 
    if (fp) {
        char line[4096];
        while (line == fgets(line, 4096, fp)) {

                        NSLog(@"length:%d line:%s", strlen(line), line);
            isFgetsOK = YES;
        }
        pclose(fp);
    }
    else {

        NSLog(@"popen error");
    }   
    if (!isFgetsOK) {
        NSLog(@"fgets error");
    }
    }

そして、ログを取得しました:

19:56:23.781 TopDemo[856:a0f] length:29 line:  PID TTY           TIME CMD
19:56:23.782 TopDemo[856:a0f] length:31 line:  744 ttys000    0:00.02 -bash
19:56:24.781 TopDemo[856:a0f] length:29 line:  PID TTY           TIME CMD
19:56:24.782 TopDemo[856:a0f] length:31 line:  744 ttys000    0:00.02 -bash
19:56:25.781 TopDemo[856:a0f] length:29 line:  PID TTY           TIME CMD
19:56:25.782 TopDemo[856:a0f] length:31 line:  744 ttys000    0:00.02 -bash
19:56:26.780 TopDemo[856:a0f] length:29 line:  PID TTY           TIME CMD
19:56:26.781 TopDemo[856:a0f] length:31 line:  744 ttys000    0:00.02 -bash
19:56:27.782 TopDemo[856:a0f] fgets error
19:56:28.781 TopDemo[856:a0f] length:29 line:  PID TTY           TIME CMD
19:56:28.782 TopDemo[856:a0f] length:31 line:  744 ttys000    0:00.02 -bash
19:56:29.781 TopDemo[856:a0f] length:29 line:  PID TTY           TIME CMD
19:56:29.782 TopDemo[856:a0f] length:31 line:  744 ttys000    0:00.02 -bash
19:56:30.781 TopDemo[856:a0f] length:29 line:  PID TTY           TIME CMD
19:56:30.782 TopDemo[856:a0f] length:31 line:  744 ttys000    0:00.02 -bash
19:56:31.781 TopDemo[856:a0f] length:29 line:  PID TTY           TIME CMD
19:56:31.782 TopDemo[856:a0f] length:31 line:  744 ttys000    0:00.02 -bash
19:56:32.781 TopDemo[856:a0f] length:29 line:  PID TTY           TIME CMD
19:56:32.782 TopDemo[856:a0f] length:31 line:  744 ttys000    0:00.02 -bash
19:56:33.781 TopDemo[856:a0f] length:29 line:  PID TTY           TIME CMD
19:56:33.782 TopDemo[856:a0f] length:31 line:  744 ttys000    0:00.02 -bash
19:56:34.781 TopDemo[856:a0f] length:29 line:  PID TTY           TIME CMD
19:56:34.782 TopDemo[856:a0f] length:31 line:  744 ttys000    0:00.02 -bash
19:56:35.781 TopDemo[856:a0f] length:29 line:  PID TTY           TIME CMD
19:56:35.782 TopDemo[856:a0f] length:31 line:  744 ttys000    0:00.02 -bash
19:56:36.781 TopDemo[856:a0f] length:29 line:  PID TTY           TIME CMD
19:56:36.782 TopDemo[856:a0f] length:31 line:  744 ttys000    0:00.02 -bash
19:56:37.781 TopDemo[856:a0f] length:29 line:  PID TTY           TIME CMD
19:56:37.783 TopDemo[856:a0f] length:31 line:  744 ttys000    0:00.02 -bash
19:56:38.781 TopDemo[856:a0f] length:29 line:  PID TTY           TIME CMD
19:56:38.782 TopDemo[856:a0f] length:31 line:  744 ttys000    0:00.02 -bash
19:56:39.781 TopDemo[856:a0f] length:29 line:  PID TTY           TIME CMD
19:56:39.782 TopDemo[856:a0f] length:31 line:  744 ttys000    0:00.02 -bash
19:56:40.781 TopDemo[856:a0f] length:29 line:  PID TTY           TIME CMD
19:56:40.782 TopDemo[856:a0f] length:31 line:  744 ttys000    0:00.02 -bash
19:56:41.782 TopDemo[856:a0f] fgets error
19:56:42.783 TopDemo[856:a0f] fgets error
19:56:43.782 TopDemo[856:a0f] fgets error
19:56:44.781 TopDemo[856:a0f] length:29 line:  PID TTY           TIME CMD
19:56:44.782 TopDemo[856:a0f] length:31 line:  744 ttys000    0:00.02 -bash
19:56:45.781 TopDemo[856:a0f] length:29 line:  PID TTY           TIME CMD
19:56:45.782 TopDemo[856:a0f] length:31 line:  744 ttys000    0:00.02 -bash
19:56:46.782 TopDemo[856:a0f] fgets error
19:56:47.781 TopDemo[856:a0f] length:29 line:  PID TTY           TIME CMD
19:56:47.782 TopDemo[856:a0f] length:31 line:  744 ttys000    0:00.02 -bash
19:56:48.781 TopDemo[856:a0f] length:29 line:  PID TTY           TIME CMD
19:56:48.782 TopDemo[856:a0f] length:31 line:  744 ttys000    0:00.02 -bash

そして、アプリを何度か実行しようとすると、「fgetsエラー」がランダムに出てきます...

4

1 に答える 1

0

マンページから (http://pubs.opengroup.org/onlinepubs/007908799/xsh/fgets.html):

正常に完了すると、fgets() は s を返します。ストリームがファイルの終わりにある場合、ストリームのファイルの終わり標識が設定され、fgets() はヌル・ポインターを戻します。読み取りエラーが発生すると、ストリームのエラー標識が設定され、fgets() は NULL ポインターを戻し、エラーを示すために errno を設定します。

ファイルの終わりに null を返し、ファイルが 4096 文字未満の場合、最初の繰り返しで EOF に達するため、isFgetsOK = YES;到達しません。

申し訳ありませんが、解釈が間違っています...呼び出し中にストリームがEOFに達した場合ではなく、fgetsが呼び出されたときにストリームがEOFにある場合はnullを返します... ^^ ;

于 2011-02-17T08:36:00.290 に答える