2010-08-04 42 views
2

我正在製作一個小型的基於控制檯的RPG,來刷新我的編程技巧。 我正在使用結構來存儲字符數據。事情就像他們的HP,力量,也許庫存在路上。我需要做的關鍵事情之一是加載和保存字符。這意味着閱讀和保存結構。爲什麼我的程序讀取額外的結構?

現在我只是保存和加載一個名字和姓氏的結構,並試圖正確閱讀它。

這裏是我創造一個字符代碼:

void createCharacter() 
{ 
    char namebuf[20]; 

    printf("First Name:"); 

    if (NULL != fgets(namebuf, 20, stdin)) 
    { 
     char *nlptr = strchr(namebuf, '\n'); 
     if (nlptr) *nlptr = '\0'; 
    } 
    strcpy(party[nMember].fname,namebuf); 


    printf("Last Name:"); 
    if (NULL != fgets(namebuf, 20, stdin)) 
    { 
     char *nlptr = strchr(namebuf, '\n'); 
     if (nlptr) *nlptr = '\0'; 
    } 
    strcpy(party[nMember].lname,namebuf); 

    /*Character created, now save */ 
    saveCharacter(party[nMember]); 
    printf("\n\n"); 
    loadCharacter(); 

} 

這裏是saveCharacter功能:

void saveCharacter(character party) 
{ 
    FILE *fp; 
    fp = fopen("data","a"); 
    fwrite(&party,sizeof(party),1,fp); 
    fclose(fp); 

} 

和loadCharacter功能

void loadCharacter() 
{ 
    FILE *fp; 

    character tempParty[50]; 
    int loop = 0; 
    int count = 1; 
    int read = 2; 

    fp= fopen("data","r"); 

    while(read != 0) 
    { 
     read=fread(&tempParty[loop],sizeof(tempParty[loop]),1,fp); 
     printf("%d. %s %s\n",count,tempParty[loop].fname,tempParty[loop].lname); 
     loop++; 
     count++; 
    } 
    fclose(fp); 
} 

這樣的預期效果該程序是我輸入姓名和姓氏,如'John Doe',並將其附加到數據文件。然後它被讀入,可能類似於

1. Jane Doe 
2. John Doe 

並且程序結束。

但是,我的輸出似乎在最後增加了一個空白結構。

1. Jane Doe 
2. John Doe 
3. 

我想知道這是爲什麼。請記住,我正在讀取文件,直到fread返回0來表示它碰到EOF。

謝謝:)

+0

對於後人,我結束了持續的解決方案是,以保持我的代碼相同,與小添加嵌套的,如果同時裏面,檢查讀取在它到達printf之前。 – Blackbinary 2010-08-04 15:09:39

回答

3

更改您的循環:

while(fread(&tempParty[loop],sizeof(tempParty[loop]),1,fp)) 
{ 
    // other stuff 
} 

每當你寫的文件中讀取代碼問自己這個問題 - 「如果我讀了一個空文件會發生什麼?」

+0

謝謝,這是所有的答案。我現在明白自己的錯誤,並且自從你找到了最優雅的解決方案,並且最容易實施,我會讓你成爲公認的答案。 – Blackbinary 2010-08-04 14:44:29

1

這裏:

read=fread(&tempParty[loop],sizeof(tempParty[loop]),1,fp); 
    printf("%d. %s %s\n",count,tempParty[loop].fname,tempParty[loop].lname); 

你是不是檢查讀取是否成功(的fread()的返回值)。

2

你在你的循環有一個算法問題,將其更改爲:

read=fread(&tempParty[loop],sizeof(tempParty[loop]),1,fp); 
while(read != 0) 
{ 
     //read=fread(&tempParty[loop],sizeof(tempParty[loop]),1,fp); 
     printf("%d. %s %s\n",count,tempParty[loop].fname,tempParty[loop].lname); 
     loop++; 
     count++; 
     read=fread(&tempParty[loop],sizeof(tempParty[loop]),1,fp); 
} 

有辦法擺脫GED雙FREAD的,但首先讓它工作,並確保你理解的流動。

0

你已經得到了你的直接問題的答案,但值得指出的是,盲目地寫作和閱讀整個結構不是一個好的計劃。

結構佈局可以並且確實會根據您使用的編譯器,編譯器的版本以及使用的確切編譯器標誌進行更改。這裏的任何更改都會破壞您讀取使用不同版本保存的文件的能力。

如果您有支持多種平臺問題的雄心壯志,例如排序也會發揮作用。

再有就是,如果你添加元素在以後的版本的結構會發生什麼...

對於穩健性,你需要考慮獨立定義文件格式的代碼,並讓您的保存和加載函數處理連載並從這種格式反序列化。

+0

我同意,但這並不嚴重。正如我剛纔提到的那樣,在課程再次開始之前,它只是練習我的編程技巧。 – Blackbinary 2010-08-04 23:53:57

1
while(1==fread(&tempParty[loop],sizeof*tempParty,1,fp)) 
{ 
/* do anything */ 
} 

是正確的方法。

使用fopen("data","rb") 代替fopen("data","r")這相當於fopen("data","rt")

相關問題