2013-01-20 28 views
0

我試圖模仿Unix工具貓的行爲,但是當我打電話的形式的命令不讀:從標準適當

貓文件1 - 文件2 - 文件3

我的程序將輸出file1正確,然後從標準輸入讀入,然後當我按下EOF時,它將打印文件2,然後是文件3,而不從第二次讀取標準輸入。

爲什麼會這樣呢?

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#define ASCII_LENGTH 255 
int printfile(FILE *source, int N); 

int main(int argc, char *argv[]) 
{ 
    int currentarg = 1; //the argument number currently being processed 

    FILE *input_file; 
    //if there are no arguments, dog reads from standard input 
    if(argc == 1 || currentarg == argc) 
    { 
     input_file = stdin; 
     printfile(input_file,0); 
    } 
    else 
    { 
     int i; 
     for(i = currentarg; i < argc; i++) 
     { 
      printf("%d  %s\n",i,argv[i]); 
      //if file is a single dash, dog reads from standard input 
      if(strcmp(argv[i],"-") == 0) 
      { 
       input_file = stdin; 
       printfile(input_file,0); 
       fflush(stdin); 
       fclose(stdin); 
       clearerr(stdin); 
      } 
      else if ((input_file = fopen(argv[i], "r")) == NULL) 
      { 
       fprintf(stderr, "%s: %s: No such file or directory\n", argv[0], argv[i]); 
       return 1; 
      } 
      else 
      { 
       printfile(input_file,0); 
       fflush(input_file); 
       fclose(input_file); 
       clearerr(input_file); 
      } 
     } 
    } 
    return 0; 
} 

int printfile(FILE *source, int N) 
{ 
    //used to print characters of a file to the screen 
    //characters can be shifted by some number N (between 0 and 25 inclusive) 
    char c; 
    while((c = fgetc(source)) != EOF) 
    { 
     fputc((c+N)%ASCII_LENGTH,stdout); 
    } 
    printf("***** %c  %d",c,c==EOF); 
    return 0; 
} 
+0

我不認爲你考慮看[貓的源代碼](http://www.scs.stanford.edu/histar//src/pkg/cat/cat.c) – paddy

+0

'fopen'失敗除了'ENOENT'之外的許多原因。檢查「strerror」和「perror」文檔。不要理由:讓系統告訴你。 –

+1

您關閉'stdin',難怪它下次關閉;-) – vonbrand

回答

4

一件事,你不能期望能夠從stdin讀取你已經關閉後:

  fclose(stdin); 
+0

它的工作原理!謝謝 – nope

+1

@nope嘗試'clearerr(stdin);'而不是關閉。 –

1

fflush(stdin);是不確定的行爲,是fflush上的所有文件只開放用於輸入。這就像沖洗馬桶,並期待浪費從碗裏出來,因爲fflush只定義爲打開輸出的文件!如果你想放棄一行的其餘部分,我會建議類似for (int c = fgetc(stdin); c >= 0 && c != '\n'; c = fgetc(stdin));

此外,fgetc返回int一個理由:int內則是一個unsigned char值或EOFc應該是一個int,而不是charEOF不是一個字符!這是一個負值int值。這區別於任何可能的字符,因爲成功調用fgetc將只返回正整數而不是負EOFfputc預計以unsigned char值的形式輸入。 char不需要是unsigned。提供fgetc呼叫成功,您將返回值存儲到int中,即int應安全地傳遞到fputc