2015-08-21 105 views
1

我是C++編碼的新手。我的應用程序需要將變量寫入文件,然後我想再次閱讀它們以完成一些工作。從文件中讀取錯誤的值

我將值賦給變量,然後轉儲到文件上,但是當我讀取文件並檢查變量時,它將賦予不同的值。 下面是我正在使用的3個結構。

struct fence_t 
{ 
    uint8_t b:1; 
    uint8_t fence_1:2; 
    uint8_t fence_2:2; 
    uint8_t res:3; 
}; 

struct head_t 
{ 
    uint8_t format; 
    fence_t fence; 
}; 

struct pack_t 
{ 
    head_t header; 
    . 
    . 
    . 
} 

我已經指定格式= 2

packet[i].header.format=2; 
packet[i].header.fence.b=0;   
packet[i].header.fence.fence_1=2; 
packet[i].header.fence.fence_2=2; 
packet[i].header.fence.res=0; 

我這是怎麼打開的文件,並傾倒在它的數據。我想要以十六進制格式寫入值。

f = fopen("packets.txt","w"); 

fprintf(f, "%04X", packet[i].header); 

現在在另一個函數中我想讀取文件。

ff.seekg(0,ios::end); 
    size=ff.tellg(); 
    memblock = new pack_t [size/sizeof(pack_t)]; 
    ff.seekg(0,ios::beg); 
    ff.read((char *)memblock,size); 

    void * p = (void *)memblock;  

    for(int i=0;i<3;i++) 
    { 
     struct q_entry_t t = {i, p}; 
     queue1.push_back(t); 
     p = (void *)((uintptr_t)p+64); 
    } 

當我檢查格式的值它顯示1.

cout<<((head_t *)p)->format<<endl; 

這是存儲窗口的Visual Studio中的輸出時,我看在p

0x026A54B8 31中的值34 30 32 30 30 30 31 30 31 30 30 30 30 30 31 30 30 140200010100000100

+3

好像你正在寫作ASCII並試圖讀回二進制。您想做什麼? – pm100

+1

爲了清楚起見,當你這樣做時,你的工具鏈不會*發出警告:'fprintf(f,「%04X」,packet [i] .header);'?即發送一個'head_t'到一個'printf'-family說明符,它需要一個無符號整數?有趣。轉到C/C++項目屬性並打開警告級別。應該已經檢測到了。 – WhozCraig

+0

使用'fwrite'會好很多,它不會指望任何格式化的輸入。如果你熟悉C++做這些事情的方法(儘管它有點難),而不是舊的C方式,那麼你會更好。 – Wug

回答

1

一般情況下,如果你用fprintf寫,然後回讀fscanf或getline;即一個面向行/ ASCII的輸入機制。

如果您希望文件被構造爲二進制文件,那麼使用read和write進行寫入和讀取。

不要混合這兩種機制

+0

感謝您的幫助 –

1

有幾個問題:

  • 你的價值由fprintf()通過packet[i].header,並告訴fptrintf()這是一個int,而且其值應以ASCII十六進制格式寫入。你的編譯器可能會傳遞你的值爲int的大小,你會得到一個可用的值。但是你的編譯器可能會傳遞比int更多或更少的數據(因爲你的頭文件是一個結構體並且可能會受到對齊填充的影響),然後,你寫的值將不會是你所期望的。所以它非常依賴於實現。

  • 順便說一句,即使您的編譯器傳遞了適當大小的值,由於字節順序,您可能會有非可移植文件。

  • 然後,你讀取你的數據,就好像它是二進制文件(不打開文件爲「rb」反正會造成嚴重破壞)。因此,您只會讀取部分ASCII數據,並且完全不同地解釋編碼(即,您寫'1',但您會讀取0x31)。那也行不通。你必須按照與你寫的邏輯相同的邏輯,用fscanf()來閱讀它。但是,如上所述,這是非常依賴於實施的。

作爲很不錯的選擇,我會建議你打開該文件作爲二進制fstreams,使用ios::binary,並使用write()/read()寫的內存塊,使用您的數據元素,並且其確切大小的地址。

作爲更便攜的替代,可以使用文本文件流,和過載<<>>head_t類型爲使用很好的控制(即固定的字節順序)十六進制格式。

+0

謝謝,我明白了.. –