2015-04-12 124 views
2

我有一個菜單程序。結構稱爲「Siunta」,結構中帶有稱爲「nauja」的新值。我試圖將它寫入文件,然後從文件中讀取。閱讀和寫作的功能在下面提供。編譯器中的錯誤消息:C - 試圖從文件讀取結構

|144|error: 'Siunta' undeclared (first use in this function)|.

什麼可能是錯誤的?

寫作:

FILE* fp = fopen("file.bin", "wb"); 
struct Siunta nauja; 
fwrite(&(nauja.siuntos_nr), sizeof(nauja.siuntos_nr), 1, fp); 
fwrite(&(nauja.destination), sizeof(nauja.destination), 1, fp); 
fwrite(&(nauja.svoris), sizeof(nauja.svoris), 1, fp); 
fclose(fp); 

閱讀:

FILE* fp = fopen("file.bin", "rb"); 
struct Siunta nauja2;   
fread(&nauja2, sizeof(Siunta),1,fp);  
printf("siuntos nr: %d destination: %s Svoris: %d",nauja2.siuntos_nr, nauja2.destination, nauja2.svoris); 
+3

要小心結構的讀/寫。由於您逐字段地編寫它,因此文件中的數據將不具有實際結構使用的可能的填充,因此當您閱讀它時,結果可能不符合您的期望。你應該以同樣的方式讀寫結構,不論是逐場還是整個結構,不要混合它。 –

+1

@JoachimPileborg在這裏提出了非常重要的一點。知道誰可能讀取該文件也是可取的。如果一個不同的架構讀取它,它可能會有不同的填充,並且可能無法寫入/讀取整個結構。字節順序也很重要。一個不同的endian機器將不得不在讀取後轉換這些值。 – holgac

回答

1

你需要寫struct Siunta,而不是Siunta在:

fread(&nauja2, sizeof(Siunta),1,fp); 

或者,您可以事先創建一個typedef,這樣:

typedef struct Siunta Siunta; 
+0

不要typedef結構體定義。這樣的typedef混亂了代碼,降低了可視性,使代碼更難理解,可能(並且經常是)誤導,並且使編譯器名稱空間混亂。 – user3629249

+0

這是一個有效的觀點,但我不認爲應該無條件地禁止struct typedefs。我認爲,就像goto一樣,這是一個經常會讓你的代碼混淆的工具,但是如果你正確地使用它,有時會更自然。 – tux3

+0

非常奇怪的是,非常討厭的typedefs在C的標準包含文件中無處不在。 ...還有很多C++包括!我們不得不認爲C/C++開發者瘋了嗎? ;) –

0

只需按字段編寫結構字段。也使用網絡訂購號碼。這將使它在未來可以證明,並在開始時加入版本號。

+0

那麼你也必須閱讀它字段的字段! –

+1

是的 - 問題是。它具有能夠在多個平臺上工作的優點,並且可以處理不同版本的軟件 –

+0

或者 - 強制打包('#prgama pack'),這就是我通常所做的(我正在懶惰......); - ) –

3

發生的錯誤是由於sizeof(Siunta)可能是sizeof(struct Siunta),但您也可以使用sizeof(nauja2)(可能更好)。

讀你的代碼,我看你已經寫了一些結構Siunta的字段,但是想讀完所有的結構後!

你必須寫使用結構:

fwrite(&nauja, sizeof(nauja), 1, fp); 

然後你可以閱讀:

fread(&nauja2, sizeof(nauja2), 1, fp); 
+0

嗨,我是這麼寫的,就像你上面寫的那樣。 Printf向我展示一些不可理解的標誌,數字等,但不是正確的結構元素... – rimasbimas

+0

它可能與此警告有關嗎?我有他們的結構的所有條目。警告:格式'%s'需要類型爲'char *'的參數,但參數2的類型爲'char(*)[20]'[-Wformat =] | – rimasbimas

+0

閱讀您發佈的代碼,我無法理解這個其他警告! ...在代碼中,我看到printf看起來是正確的,但要確保我需要結構的聲明(我認爲Siunta),並且需要生成警告的一行。提示可能是您使用了%c而不是%s,但我不確定! –