2015-01-03 56 views
-2

請幫幫我。這是我的代碼到目前爲止。刪除記錄功能不起作用,有人可以用以下條件幫助更新記錄功能:

- 要求用戶輸入玩家名稱。
- 要求用戶輸入玩家分數。
- 要求用戶輸入玩家等級。
- 如果列表中不存在玩家名稱,則顯示消息「找不到玩家名稱的名稱!更新文件中的記錄文件

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

struct Player { 
    char name[50]; 
    int score; 
    int level; 
}; 
struct Player data[50]; 
FILE *ptr; 
FILE *ptr2; 

int fileSize() 
{ 
    int lSize; 
    int end; 
    ptr = fopen("text.txt", "r"); 
    lSize = ftell (ptr); 
    fseek (ptr, 0, SEEK_END); 
    end = ftell (ptr); 
    fseek (ptr, lSize, SEEK_SET); 

    return end; 
} 

int getNoOfRecords() 
{ 
    return (fileSize()/(sizeof(struct Player))); 
} 

void deletePlayerRecord() 
{ 
    char name[50]; 
    int counter=0, i=0; 

    ptr2 = fopen("text2.txt","a"); 
    int records = getNoOfRecords(); 

    ptr = fopen("text.txt","a+"); 
    do { 
     printf("Input player name[1..10]: "); 
     scanf("%[^\n]s", name); 
     fflush(stdin); 
    } while (strlen(name)<1 || strlen(name)>10); 
    while(counter!=records) 
    { 
     fread(&data,sizeof(struct Player),1,ptr); 
     if(strcmp(data[i].name,name)==0) 
     { 

     } 
     else 
     { 
      fwrite(&data,sizeof(struct Player),1,ptr2); 
     } 
     counter++; 
    } 
    fclose(ptr); 
    fclose(ptr2); 
    remove("text.txt"); 
    rename("text2.txt","text.txt"); 
    printf("\n%s successfully deleted.\n\n", name); 
    printf("Press Enter to continue....\n\n"); 
    getchar(); 
} 

void updatePlayerRecord() 
{ 
    char name[50]; 
    int counter=0, i=0; 
    int records = getNoOfRecords(); 
    ptr = fopen("text.txt","a+"); 
    do { 
     printf("Input player name[1..10]: "); 
     scanf("%[^\n]s", name); 
     fflush(stdin); 
    } while (strlen(name)<1 || strlen(name)>10); 
    if(counter!=records) 
    { 
     fread(&data,sizeof(struct Player),1,ptr); 
     if(strcmp(data[i].name,name)==0) 
     { 

     } 
     counter++; 
    } 
    printf("\nScore and Level successfully updated.\n\n"); 
    printf("Press Enter to continue....\n\n"); 
    getchar(); 
} 

void addPlayerRecord(){ 
    int i=0; 
    do { 
     printf("Input player name[1..10]: "); 
     scanf("%[^\n]s", data[i].name); 
     fflush(stdin); 
    } while (strlen(data[i].name)<1 || strlen(data[i].name)>10); 
    fflush(stdin); 
    getchar(); 
    data[i].score=0; 
    data[i].level=0; 

    ptr = fopen("text.txt", "a"); 
    printf("\n"); 
    fprintf(ptr, "\r\n%s#%d#%d", data[i].name, data[i].score, data[i].level); 
    fclose(ptr); 

    printf("\nData successfully added.\n\n"); 
    printf("Press Enter to continue....\n\n"); 
    getchar(); 
} 


void viewPlayerRecord(){ 
    int i=0; 
    ptr = fopen("text.txt", "r"); 
    printf("Player Name\t\t|Average Score\t|Number of Playing\n"); 
    printf("=======================================================\n"); 
    while(fscanf(ptr, "%[^#]#%d#%d\n", data[i].name, &data[i].score, &data[i].level)!=EOF) 
    { 
     printf("%s\t\t\t|%d\t\t\t\t|%d\n", data[i].name, data[i].score, data[i].level); 
     i++; 
    } 
    fclose(ptr); 
} 

int main() { 
    int choice; 
    do{ 
     printf("Score Record Dota Player\n"); 
     printf("========================\n"); 
     printf("1. View Record\n"); 
     printf("2. Update Player Record\n"); 
     printf("3. Add New Player\n"); 
     printf("4. Delete Player\n"); 
     printf("5. Save and Exit\n\n"); 
     do { 
      printf("Input your choice[1..5]: "); 
      scanf("%d", &choice); 
      fflush(stdin); 
      getchar(); 
     } while (choice < 1 || choice > 5); 

     switch (choice) { 
      case 1: 
       viewPlayerRecord(); 
       break; 

      case 2: 
       updatePlayerRecord(); 
       break; 

      case 3: 
       addPlayerRecord(); 
       break; 

      case 4: 
       deletePlayerRecord(); 
       break; 
     } 
    } while(choice!=5); 
    return 0; 
} 
+0

代碼審查請求在這裏不正確 – maxpovver

+0

如果需要幫助/刪除功能,請提供有關該問題的詳細信息。如果您要求某人爲您編寫更新功能,請查看其他地方。 –

+0

0)你在'fileSize'處忘了'fclose(ptr)'。 – BLUEPIXY

回答

0

有許多問題與您的代碼:

  • 每個操作適用於數據庫文件。這可能是一個很好的設計,但更常用的方法是在啓動時將數據庫加載到內存中,即填充您的data然後處理此問題。退出程序時,您將對數據庫文件進行所有更改。 (您的選項5命名爲「保存並退出」,但實際上是空操作,該名稱暗示了概述的方法)。

  • 您應該下定決心,無論您的數據庫是二進制文件還是文本文件。當您添加和顯示記錄時,使用fprintffscanf(用於文本文件),但在更新和刪除記錄時使用fwritefread(用於二進制文件)。在我看來,二進制訪問比較容易,因爲你只需要存儲和檢索固定大小的塊即sizeof(struct Player)。文本文件更加用戶友好,因爲它們可以在文本編輯器中顯示和修改,但它們必須經過分析並需要更高級的錯誤處理。

  • 你的fileSize()只能用於二進制文件,但目前你只寫文本文件。通常使用文件函數的返回值來確定讀取或寫入是否成功通常會更好。

  • 當數據庫文件不存在時,您的視圖函數將崩潰。檢查文件的存在和正確的格式。

  • 此刻,您只使用data作爲暫存空間。你osften訪問data[i],但i在整個代碼中爲零。

一個修正刪除功能的工作原理是:

void deletePlayerRecord() 
{ 
    struct Player p; 
    char name[50]; 
    int del = 0; 

    ptr2 = fopen("text2.txt", "w"); 
    ptr = fopen("text.txt", "r"); 

    do { 
     printf("Input player name[1..10]: "); 
     scanf("%[^\n]s", name); 
     fflush(stdin); 
    } while (strlen(name)<1 || strlen(name)>10); 

    while (fscanf(ptr, "%[^#]#%d#%d\n", p.name, &p.score, &p.level) == 3) { 
     if(strcmp(p.name, name) == 0) { 
      printf("\n%s successfully deleted.\n\n", name); 
      del++; 
     } else { 
      fprintf(ptr2, "%s#%d#%d\n", p.name, p.score, p.level); 
     } 
    } 
    fclose(ptr); 
    fclose(ptr2); 
    remove("text.txt"); 
    rename("text2.txt", "text.txt");  

    printf("%d character(s) deleted\n\n", del); 
} 

此代碼仍然存在許多弊端:

  • fopen成功不檢查。

  • fscanffprintf格式必須從視圖逐字複製並添加記錄選項。這是不好的風格。你應該寫readPlayerwritePlayer函數。

  • 輸入代碼也是如此。編寫進行錯誤檢查的前端函數,以便不必一遍又一遍地重複整個代碼。這使代碼難以閱讀,並且容易出錯。