2016-07-06 67 views
2

雖然我試圖使用fread()將文件複製到字符串中,但我從文件中獲得了與新行數完全相同的額外字符。 這裏是我的代碼:爲什麼fread()在c中讀取額外的'#newlines'字符?

#include <stdio.h> 
#include <stdlib.h> 
#define LEN 5000000 

int main() 
{ 
    char *in = (char*) malloc(LEN); 
    FILE *f=fopen("in.txt","r"); 
    fread(in,5000000,1,f); 
    printf("%ld\n", ftell(f)); 
    in[ftell(f)]=0; 
    int l; 
    for(l=0;true;l++) 
    { 
     if(in[l]<10) 
     break; 
     printf("%d ",in[l]); 
    } 
    printf("\n"); 
} 

輸入此程序是:

1 
2 
<newline> 

鏈接,輸入:https://paste.fedoraproject.org/388281/46780193/
對於輸出我正在打印字符的ASCII值改爲:

6 
49 10 50 10 13 10 

如果輸入是:

1 
2 
3 
<newline> 

鏈接,輸入:https://paste.fedoraproject.org/388280/
則輸出爲:人物

9 
49 10 50 10 51 10 51 13 10 

我看到一些其他的測試cases.In每個測試用例額外數量總是新的行數。我有幾個問題:
- 爲什麼模式是這樣的?
- 這是怎麼回事,新行佔用2個字節的窗口?
- 如何擺脫這些額外的字符?
我搜索了類似的問題,但沒有找到答案。請解釋一下?

+2

爲什麼?因爲這正是文件中的內容。換行符('\ n')需要在那裏表示一個*新行*。有很多方法可以擺脫換行符。最好的方法取決於你想要達到的目標。請參閱例如[從fgets()輸入]中刪除尾隨換行符(請參見http://stackoverflow.com/questions/2693776/removing-trailing-newline-character-from-fgets-input) – kaylum

+0

請顯示文件的確切內容。 – 2501

+0

另外,爲什麼不使用'LEN',而是專門定義的,而不是在'fread()'調用中輸入數字? – Magisch

回答

2

在以文本模式打開的流上調用ftell(例如在您的示例中)無意義。

函數fread的用法不正確,大小和計數參數被切換。這意味着讀取始終是部分的,因爲您的文件中沒有5000000個字符。因此,調用後數組中元素的值具有不確定的值。 (您的案例中的邏輯元素是大小爲5000000的單個元素。)

您看到的結果沒有意義。讀取不確定的值可能導致未定義的行爲。

閱讀您的文件正確的方法是正確的參數傳遞給FREAD和使用返回值來確定成功讀取字符數:

#include <stdio.h> 
#include <stdlib.h> 
#include <stdbool.h> 
#include <assert.h> 

int main() 
{ 
    unsigned char in[500] = { 0 } ; 
    FILE *f=fopen("in.txt","r"); 
    assert(f) ; 

    const size_t read = fread(in,1,500,f); 
    printf("read: %zu\n" , read); 

    for(size_t index = 0 ; index < read ; index++) 
    { 
     printf("%hhu " , in[index]); 
    } 

    fclose(f); 
} 

使用這種正確的程序,當文件中有內容(點不是文件的一部分):

. 
1 
2 
3 

. 

將讀取並打印正確的值:

read: 7 
49 10 50 10 51 10 10 

一個換行符,代表的值爲10,對於每個數字,並且在結尾處增加一個換行符。


(引自:ISO:IEC 9899:201X 7.21.9.4的FTELL功能2)
對於文本流,它的文件位置指示器包含未指定 信息,由用於FSEEK功能可用將流的 的文件位置指示符返回到它在全部呼叫時的位置;兩個這樣的返回值之間的差異不一定是寫入或讀取的字符數量的有意義的度量。

(引自:ISO:IEC 9899:201X 7.21.8.1 fread函數2)
如果部分元件被讀取時,它的值是不確定的。

在windows文件中,換行符由兩個字符表示:13,10。回車符和換行符。但是當以文本模式閱讀文件時,換行符總是換行符:10.由於程序的行爲沒有意義,因此您看到了字符13。如果(正確)打開並以二進制模式讀取文件,則會看到由兩個字符表示的換行符。

-1

如果您使用的是Windows和編輯in.txt使用一些編輯器,附加CR-LF(回車,換行)((ASCII)13,10),以每個換行符這必將發生的文件。嘗試通過程序編寫in.txt然後閱讀它。這將如預期般完成。或者使用不附加CR-LF的編輯器(行尾)。對不起,我不知道沒有這樣的編輯器[但是一些Linux編輯會工作。]。

相關問題