2014-03-02 41 views
1

我花了很多時間試圖找到一個解決方案如何寫入和從文件讀取結構,並完全卡住。如何使用write/fread將數據寫入/讀取結構數組?

代碼應該很簡單,但我想我已經錯過了關於fwrite/fread的相當重要的細節。我認爲寫作正在發揮作用,但我並不完全確定。一旦我嘗試讀入數組,我會在k=1上得到分段錯誤錯誤。

如果有人能指導我在什麼方向進一步移動,我將最終高興。

#include <stdio.h> 

struct Student { 
char matrikl[6]; 
char shortName[6]; 
int value1; 
int value2; 
int value3; 
int value4; 
int money; 
}xStudent; 

int calcMoney(int,int,int,int); 

int main(void) 
{ 
int i=0; 
printf("How much students to insert!\n"); 
scanf("%i",&i); 
    struct Student S[i]; 

for (int var = 0; var < i; ++var) { 
    printf("insert student data\n"); 
    printf("Matriklinumber\n"); 
    scanf("%s", S[var].matrikl); 
    printf("Student name\n"); 
    scanf("%s", S[var].shortName); 
    printf("Insert values!\n"); 
    scanf("%i%i%i%i",&S[var].value1,&S[var].value2,&S[var].value3,&S[var].value4); 
    S[var].money=calcMoney(S[var].value1,S[var].value2,S[var].value3,S[var].value4);; 
} 

FILE*sourcefile; 
sourcefile=fopen("text.txt","ab+"); 

for (int var = 0; var < i; ++var) { 
    fwrite(&S[var],sizeof(struct Student),1,sourcefile); 
} 
fclose(sourcefile); 


sourcefile=fopen("text.txt","rb+"); 
struct Student A[i]; 

if (sourcefile==NULL) perror ("Error opening file"); 
      else 
      { 
        int k=0; 
        while (fgetc(sourcefile) != EOF) { 
        fread(&A[k],sizeof(struct Student),1,sourcefile); 
        k++; 
        } 
      } 
fclose(sourcefile); 
return 0; 
} 

int calcMoney(int xvalue1, int xvalue2, int xvalue3, int xvalue4) 
{ 
int Sum = xvalue1+xvalue2+xvalue3+xvalue4; 
if(Sum==20) 
    return 100; 
else 
    if(Sum>=16 && Sum<20) 
     return 75; 
    else return 0; 
} 

回答

1

你有正確的想法,但是這應該解決你的問題。

for (int var = 0; var < i; ++var) { 
    fwrite(&S[i], sizeof(struct Student), 1, sourcefile); 
} 

sizeof後聲明中fwrite的參數1表示您僅希望一次添加一個學生。

請參閱文檔爲fwritehttp://www.cplusplus.com/reference/cstdio/fwrite/

而且也:

  while (fgetc(sourcefile) != EOF) { 
      fread(&A[k], sizeof(struct Student), 1, sourcefile); 
      k++; 
      } 

請參閱fread商務部:http://www.cplusplus.com/reference/cstdio/fread/

我知道這是CPLUSPLUS網站,但它是唯一的地方我可以在這些功能上找到很好的文檔。

此外,下面的數組初始化爲0的元素:

struct Student A[k]; 

你可能想嘗試管理這個鏈表來代替。

最終可能看起來像:

struct StudentList { 
    struct Student* student; 
    struct StudentList* next; 
}; 


struct StudentList* students = NULL; 

while(!feof(sourcefile)) { 
    struct StudentList* newlink = malloc(sizeof(struct StudentList)); 
    newlink->student = malloc(sizeof(struct Student)); 
    newlink->next = NULL; 

    fread(newlink->student, sizeof(struct Student), 1, sourcefile); 

    if(NULL != students) { 
     struct StudentList* iter; 
     for(iter=students; 
      NULL != iter->next; 
      iter = iter->next); // iterate to last link 

     iter->next = newlink; // add new link to the end 
    } else students = newlink; // add new link to the beginning 
} 



然後釋放你的列表,只需使用類似:

struct StudentList* iter, *head; 
for(iter=students; 
    NULL != iter;) 
{ 
    head = iter; 
    free(iter->student); 
    free(iter); 
    iter = head; 
} 
+0

的感謝!我已經糾正了fwrite函數參數,它似乎確定但仍然無法從文件讀取。調試器中的第二個數組元素符號不對應於第一個。 –

+0

@ user3369281你現在可以用代碼更新你的問題嗎?這樣我就可以更好地瞭解發生了什麼? –

+0

@ user3369281請仔細閱讀我的帖子,當涉及到'fwrite'和'fread'的參數時,當初始化A時k也是0,所以您創建一個包含0個元素的數組,並且稍後添加到k'將元素添加到您的陣列。您將需要動態分配元素到您的數組,或使用固定大小的數組。在我的答案中包含了一個使用動態分配鏈表的例子。 –

0

錯誤的是在宣言中的陣列A.

struct Student A[k]; 

k = 0;所以你得到錯誤,因爲A [1]左右,數組沒有定義。 申報改爲

struct Student A[i]; 

那麼如果代碼和語法其餘部分都很好,應該運行。

+0

我已經改正並現在正常工作。謝謝! –

0

修復FWRITE行:

fwrite(&S[i], sizeof(struct Student), 1, sourcefile);