2011-11-30 88 views
0

我有以下代碼,我試圖讀取文件的內容並顯示它,並寫入另一個文件。我的問題是我在屏幕上獲得的內容與文件的內容完全不同。我已經把結果的文件和部分的內容部分顯示如何讀取使用fread()中的結構的內容c

#include<iostream> 
#include <stdint.h> 
#include <stdio.h> 
struct test 
{ 
uint64_t start; 
uint16_t length; 
struct test *next; 
}; 

void main() 
{ 
    char frd[32]; 
     std::cout<<"\nEnter name of file to read?\n"; 
    std::cin>>frd; 
    FILE *rd=fopen(frd,"r+b"); 
    FILE *wrt=fopen("abc2.doc","w+"); 
    struct test test_st; 

    while(fread (&test_st, sizeof(test_st), 1, rd)) 
{ 
     fwrite (&test_st,sizeof(test_st),1,wrt); 
    printf("%llu,%u\n", test_st.start, test_st.length); 
} 
fclose(rd); 
fclose(wrt); 
} 

源文件的部分內容:顯示

0,43 
43,95 
138,159 
297,279 
576,153 
729,64 

一是結果的幾行:

3474018176930688048,13879 
3472896773804077344,14136 
4049914982932231728,13362 
3978707281317738034,12342 
3474306356368193848,14132 
3688511012684903220,14130 
724298015681099573,13624 

源文件和目標文件具有精確副本

回答

1

這是一些工作代碼。我離開了寫作部分,因爲我不知道你在找什麼樣的輸出。只要通讀閱讀邏輯,你就會知道如何修復寫作部分。

我離開了debug printf,讓你可以理解代碼是如何工作的,以及如何解析csv文件以獲得你正在尋找的結果。如上所述,該文件是一個文本(csv)文件而不是二進制文件。你試圖閱讀它的方式是讀取二進制文件。所以這種方法不會幫助。現在要讀取二進制文件,您必須將它們存儲爲二進制文件。

#include <iostream> 
#include <stdint.h> 
#include <stdio.h> 
#include <string.h> 

struct test { 
    uint64_t start; 
    uint16_t length; 
    struct test *next; 
}; 

int main(void) 
{ 
    char frd[32]; 
    std::cout<<"\nEnter name of file to read?\n"; 
    std::cin>>frd; 
    FILE *rd=fopen(frd,"r+b"); 
    FILE *wrt=fopen("abc2.doc","w+"); 
    struct test test_st; 
    char readLine[100]; 

    while(fgets(readLine, 100, rd) != NULL) { 
    // Removing the new line from the end 
    // This is a quick hack as Windows have two characters 
    // to represent new line. It is not needed to remove newline. 
    // I did so that printf output look pleasing 
    readLine[strlen(readLine) - 1] = '\0'; 
    printf("\nr=%s", readLine); 

    // Splitting the string based on ',' 
    // and then converting it to number 
    char *token = NULL; 
    token = strtok(readLine, ","); 
    test_st.start = atol(token); 
    printf("\nt1=%s, test_st.start=%llu", token, test_st.start); 

    token = strtok(NULL, ","); 
    test_st.length = atoi(token); 
    printf("\nt2=%s,test_st.length=%d", token, test_st.length); 
    //fwrite (&test_st,sizeof(test_st),1,wrt); 
    //printf("%llu,%u\n", test_st.start, test_st.length); 
    } 
    fclose(rd); 
    fclose(wrt); 
    return 0; 
} 
+0

這就是我一直在尋找的東西。太感謝了! – John

0

您應該打開wr文件它也是二進制的:

FILE *wrt=fopen("abc2.doc","w+b"); //instead of "w+" 
1

寫一個指向文件的指針是沒有意義的。回讀該指針的代碼與寫入該代碼的代碼不會有相同的內存視圖。所以不要這樣做。

取而代之,在開始編寫代碼以讀取和寫入二進制文件和從二進制文件寫入代碼之前,退後一步。二進制文件是一個字節流。因此,在文件中定義你想要的字節流。然後編寫代碼來寫出您定義的確切字節流。然後編寫代碼讀入文件,該文件具有您定義的確切字節流。

然後,如果你有問題,你會知道責怪什麼。檢查文件中的字節並確保它們符合定義。如果不是,這是作家的錯。如果是這樣,這是讀者的錯。

+0

但你能告訴我它爲什麼設法複製成功嗎? – John

+0

因爲你的測試條件是人爲的簡單化。如果你註釋掉了讀寫,你的代碼仍然會通過測試。即使您可以成功地在一個程序中寫出一個指針並將它讀回另一個程序中,讀取程序也無法通過指向不再存在的地址空間中的對象的指針。 –

+0

David我在c中沒有那麼多的知識,如果你可以用你的例子來解釋你的解釋,那將是非常不錯的。謝謝 – John

2

您的文件不包含結構,它包含以逗號分隔的值(數據的文本表示形式)。

結構以二進制形式存儲,而不是以文本形式存儲。

當您閱讀時,程序會嘗試將其讀取爲二進制文件。撤銷是:

$ printf "%x%x" 3474018176930688048 13879 | sed 's/../\\\\x&/g' | sed 's/^/echo -e /e' 
061 34,067 

讀取存儲在文本形式的數據,你可以閱讀每一行fgets,然後分析它(例如:使用sscanf())。

+0

那麼,如果我必須從文件中讀取結構內容,你能告訴我該怎麼做嗎? – John

+0

@John:首先,你需要在文件中有一個結構。 – ninjalj

+0

該文件的內容包含結構對象的元素 – John