2015-10-15 22 views
0

我想不斷從文本文件中讀取,但我不知道我在這裏做錯了什麼。它不斷打印我一些不可打印的ascii字符。爲什麼在閱讀txt文件時會出現笑臉字符?

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

int main(int argc, char **argv) 
{ 
    int n, fd; 
    char buff[256]; 
    if (argc != 2) 
    { 
     fprintf(stderr, "usage: %s <filename>\n", argv[0]); 
     return 1; 
    } 

    fd = open(argv[1], O_RDONLY); 
    if (fd < 0) 
    { 
     perror("open"); 
     return 1; 
    } 
    else if (lseek(fd, 0, SEEK_END) < 0) 
    { 
     perror("lseek"); 
     return 1; 
    } 
    else 
    { 
     while (1) 
     { 
      n = read(fd, buff, sizeof(buff)); 
      if (n < 0) 
      { 
       perror("read"); 
       break; 
      } 
      if (n == 0) 
      { 
       puts(buff); 
       Sleep(100); 
       continue; 
      } 
      if (write(STDOUT_FILENO, buff, n) < 0) 
      { 
       perror("write"); 
       break; 
      } 
     } 
    } 
    return 0; 
} 

至於我的說法,我通過包含這樣的信息的文件名:

foo-12- 

輸出是這樣的:

enter image description here

+0

什麼是您讀取的文件? – ameyCU

+1

當'read'返回'0'時,你爲什麼要調用'puts(buff)'? – Barmar

+0

@ameyCU我在另一個進程中傳遞文件名作爲參數。看看我上面提到的示例文件內容,即'foo-12 -' – Bababarghi

回答

2

的問題是該行:

puts(buff); 

read()返回0時,表示您已到達文件末尾,因此沒有任何可打印的內容。你已經用打印的文件的內容在循環的先前的重複,就行了:

write(STDOUT_FILENO, buff, n) 

puts()是印刷任何垃圾恰好是buff。並且由於buff不是空終止的,它可能會繼續打印遠遠超過數組的末尾,直到找到空字節。

擺脫那條線。

你不打印文件內容的原因是因爲在一開始你做:

lseek(fd, 0, SEEK_END) 

這轉到文件的末尾它試圖讀取任何東西之前。因此,您的程序只會顯示在啓動程序後添加到文件中的內容。由於sleep(100),它會等待100秒才能打印下一個塊。

+0

刪除'puts(buff)'這一行只清除了你正確猜測源的垃圾。 「顯示所讀內容」的問題仍未得到答覆。我還替換了'if(write(STDOUT_FILENO,buff,n))'塊,並替換爲'puts'語句仍然沒有成功。 – Bababarghi

+0

你不應該使用'puts()'。這是打印字符串,'buff'不是一個字符串。 – Barmar

+0

就是這樣。謝謝:) – Bababarghi

0

主要問題是lseek()將文件指針放在文件的末尾。

然後所有後續的讀取操作都試圖讀取文件末尾。

實際上沒有讀取任何內容,所以輸入緩衝區不變。

建議刪除調用lseek()因此呼叫的結果open()(這在文件的開頭放置文件指針)被使用。

然後調用read()將正確獲取文件內容的連續塊。

這一行:if (n == 0)說,如果沒有讀到。然而,從read()返回0意味着「文件結束」。所以你真正想要的是if (n > 0)這意味着從文件中讀取了一些字節。

行:puts(buff);將只輸出字符,直到遇到NUL字節。但是,read()不會用NUL字節終止輸入緩衝區,因此對puts()的調用可能會輸出超過buff []數組末尾的字符,導致未定義的行爲。(),buff [n] ='\ 0'或2)使用fgets()讀取緩衝區中的行,因爲fgets()會在緩衝區中附加一個緩衝區NUL字節。