3

初心者はこちら!

cat以下の私のプログラムは、Linux で (少し) コマンドのように振る舞おうとしています。

  1. 引数が指定されていない場合は、ユーザーからの入力を受け取り、画面に出力します (非常に単純なシナリオでは、入力バッファーは 10 と想定されます)。

  2. 複数の引数を渡すと、動作しています..つまり、異なるファイルの内容をプログラムどおりに1つずつ表示しています..

-- ポイントは、次のようなシェルでコマンドを実行するときです。

./mycat abc.txt > テスト

wheremycatは私のプログラム名で、abc.txtは必要なファイルで、新しいファイル テストにリダイレクトしています。私が理解できない奇妙な部分は、リダイレクト後にファイルテストを調べると、ファイルからのデータがabc.txt最初に表示され、次にprintfsとデータを表示する代わりにcプログラムのprintf関数が表示されることです。これの理由は何ですか?

int main(int argc,char *argv[])
{
    char buf[10]; 
    int x,read_bytes,i,fd;
    read_bytes=1;
    char read_buf[1024*1024];

    for(i=0;i<argc;i++)
         printf("you entered  %s\n",argv[i]); //this printf

    switch(argc)
    {
    case 1:
         x=read(0,buf,sizeof(buf));
         write(1,buf,x);
         break;

    default:
         for(i=1;i<argc;i++)
         {
             printf("showing the %dth file\n\n",i);
             fd=open(argv[i], O_RDONLY);
             if(fd==-1)
             {
                 perror("no file opened for such name");
                 exit(1);
             }
             while(read_bytes!=0)
             {
                 read_bytes=read(fd,read_buf,sizeof(read_buf));
                 if(read_bytes==-1)
                 {
                     perror("not able to read\n");
                     exit(2);
                 }
                 write(1,read_buf,read_bytes);
             }
             read_bytes=1;
             close(fd);
         }
         break;
     }

     return 0;
}
4

3 に答える 3

4

printfまたstdout、ファイル記述子がに出力されるため、ファイルの内容と同じ出力に行を1書き込んでいます。printf

次のように、診断を別の出力に書き込むことをお勧めしますstderr

fprintf(stderr, "Hello world.\n");
于 2012-01-11T19:40:19.193 に答える
2

他の答えは正しいですが、問題を説明していないようです。とstdout への書き込みの
両方。しかし、そうではありませんが、バッファリングされています。 したがって、書き込むデータは最初に何らかのバッファーに送られ、OS が選択した場合にのみ実際に書き込まれます。ただし、によって書き込まれたデータは直接ファイルに送られます。 その結果、すべてが印刷されますが、希望する順序ではありません。で印刷したデータは、後で で書き込んだデータの後に書き込むことができます。printfwrite(1)printfwrite
printfwrite
printfwrite

于 2012-01-11T21:25:58.003 に答える
1

stdout バッファがフラッシュされるようfflush(stdout)に、それぞれの後に使用してください。printfこれを実行すると、コードに従って順番に printfs が表示されます。

これが変更されたコードです。

int main(int argc,char *argv[])
{
    char buf[10]; 
    int x,read_bytes,i,fd;
    read_bytes=1;
    char read_buf[1024*1024];

    for(i=0;i<argc;i++)
        printf("you entered  %s\n",argv[i]); //this printf
    fflush(stdout);
    switch(argc)
    {
     case 1:
          x=read(0,buf,sizeof(buf));
          write(1,buf,x);
          break;

     default:
          for(i=1;i<argc;i++)
          {
              printf("showing the %dth file\n\n",i);
              fflush(stdout);
              fd=open(argv[i], O_RDONLY);
              if(fd==-1)
              {
                 perror("no file opened for such name");
                 exit(1);
              }
              while(read_bytes!=0)
              {
                 read_bytes=read(fd,read_buf,sizeof(read_buf));
                 if(read_bytes==-1)
                 {
                     perror("not able to read\n");
                     exit(2);
                 }
                 write(1,read_buf,read_bytes);
             }
             read_bytes=1;
             close(fd);
         }
         break;
     }

     return 0;
}
于 2012-01-11T20:41:02.847 に答える