2017-11-02 21 views
-1

この問題を解決するためにあなたの助けが必要な場合があります... 私はCについて学び、問題を見つけ、バイナリファイルを正しく読み込む方法を見つけます。バイナリファイルを読み込んでエントリを表示

構造体の配列が埋め込まれていて、バイナリファイルに書き込んで読み込もうとしましたが、これは何も表示されません。

コードがペーストビンである

My code

#include <stdio.h> 
#include <ctype.h> 
#include <math.h> 

typedef struct { 
    int id; 
    char name[100]; 
    char document[14]; 
    float testGrade; 
} Candidate; 

typedef struct { 
    int id; 
    float testGrade; 
} Grade; 

FILE * openFile(char filename[100], char filemode[3]) { 
    FILE *p = fopen(filename, filemode); 

    if (!p) { 
     printf("Error to open %s file. \nThe program will be closed.",filename); 
     exit(1); 
    } 
} 


void addCandidate(int newId, int numbersOfNewCandidate, char candidateFilename[100], char gradeFilename[100]) { 
    int counter = 0; 
    float testGrade = 0; 

    Candidate*candidate; 
    candidate= malloc(sizeof(Candidate) * numbersOfNewCandidate); 

    Grade *grade; 
    grade= malloc(sizeof(Grade) * numbersOfNewCandidate); 

    for(;counter< numbersOfNewCandidate; counter++) { 
     system("@cls||clear"); 
     printf("Adding #%d:",newId); 
     printf("\n---------------\n"); 

     printf("\nName of candidate: "); 
     gets(&candidate[counter].name); 

     printf("\nDocument: "); 
     gets(&candidate[counter].document); 

     do { 
      printf("\nTest grade (between 0 and 10): "); 
      scanf("%f",&testGrade); 
      printf("\n---------------\n"); 

      if (testGrade < 0 || testGrade > 10) { 
       printf("\nERROR!\nTest grade %.2f invalid, please try again with a grade between 0 and 10.\n",testGrade); 
      } 

     } while(testGrade < 0 || testGrade > 10); 

     candidate[counter].id = newId; 
     grade[counter].id = newId; 
     candidate[counter].testGrade = testGrade; 
     grade[counter].testGrate = testGrade; 
     newId++; 
     fflush(stdin); 
    } 

    FILE *candidateFile = openFile(candidateFilename, "a+b"); 
    fwrite(candidate, sizeof(candidate),numbersOfNewCandidate, candidateFile); 

    FILE *gradeFile = openFile(gradeFilename, "a+b"); 
    fwrite(grade, sizeof(grade),numbersOfNewCandidate, gradeFile); 

    fclose(candidateFile); 
    fclose(gradeFile); 

    free(candidate); 
    free(grade); 
} 

void showCandidate(int typeOfSearch, char valueToSearch[100]) {} 

void listAllCandidates(char candid[100]) { 
    FILE *fp = openFile(candidateFilename, "rb"); 

    //fseek(fp,0,SEEK_SET); 

    Candidate *candidate = NULL; 

    candidate = malloc(sizeof(Candidate) + 1); 

    while(fread(&candidate,sizeof(Candidate),1,fp) == 1) { 
     printf("\n\nId: %d \nName: %s \nDocument: %s \nGrade: %.2f",candidate->id,candidate->name,candidate->document, candidate->testGrade); 
    } 
    getche(); 
    free(candidate); 
} 

void main(){ 
    int lastId = 0; 
    char candidateFilename[100] = "candidates.bin"; 
    char gradeFilename[100] = "classificationList.bin"; 
    char option; 

    do { 
     system("@cls||clear"); 
     printf("Menu: \n"); 
     printf("1 - Add candidates \n"); 
     // printf("2 - Search by name \n"); 
     // printf("3 - Search by document \n"); 
     // printf("---------------------------\n"); 
     // printf("4 - Show Max Grade, Minimum, Avg \n"); 
     printf("5 - List candidates \n"); 
     printf("6 - Erase files \n"); 
     printf("---------------------------\n"); 
     printf("S - Exit \n"); 
     printf("\n\n"); 

     option = toupper(getche()); 

     switch(option) { 
      case '1': 
       system("@cls||clear"); 

       int numbersOfNewCandidate = 0; 
       int newId = 0; 

       printf("Home > Add candidates\n\n"); 
       printf("Please give the number of new candidates: "); 
       scanf("%d",&numbersOfNewCandidate); 
       newId = lastId; 
       lastId += numbersOfNewCandidate; 

       fflush(stdin); 
       addCandidate(newId + 1, numbersOfNewCandidate, candidateFilename, gradeFilename); 

       printf("\n\nAdding new candidates: Finished \n"); 
      break; 
      // case '2': 
      //  printf("\noption %[email protected]\n",option); 
      // break; 
      // case '3': 
      //  printf("\noption %c#\n",option); 
      // break; 
      // case '4': 
      //  printf("\noption %c?\n",option); 
      // break; 
      case '5': 
       listAllCandidates(candidateFilename); 
      break; 
      case '6': 
       remove(candidateFilename); 
       remove(gradeFilename); 
       printf("\nRemoved!!\n"); 
      break; 
      case 'S': 
       printf("\noption %c, the program will be ended...\n",option); 
      break; 
      default: 
       printf("\nWrong option!!\n"); 
      break; 
     } 
    } while (option != 'S'); 
} 

してください、あなたは私のコードに関するその他の問題を見つけた場合、まだそれについて私を解明しない... 私はすでにあまりにもそれをしようと試みたが、何もしてみてください。

+0

詳細をご覧ください。もっと詳しく。それはメニューを表示しますか? –

+0

デバッガ............. –

+0

http://idownvotedbecau.se/nodebugging/ – EJoshuaS

答えて

1
while(!feof(fp)) { 
    fread(&candidate,sizeof(Candidate),1,fp); 
    printf("\n\nId: %d \nName: %s \nDocument: %s \nGrade: %.2f",candidate->id,candidate->name,candidate->document, candidate->testGrade); 
} 
Candidate *candidate = NULL; 
candidate = malloc(sizeof(Candidate) + 1); 
while(fread(&candidate,sizeof(Candidate),1,fp) == 1) {...} 
free(candidate); 
fread

の最初のパラメータはポインタfread(void*,...)なければならない、とcandidateが既にポインタとして宣言され、それは参照演算子を持つべきではありません。正しい使用方法は次のとおりです。

while(fread(candidate,sizeof(Candidate),1,fp) == 1) {...} 

candidate


の前には言及 &オペレータが存在しないこといつかあなたが参照演算子を参照してください、それはこのような異なる場合です:

Candidate cand; 
while(fread(&cand,sizeof(cand),1,fp) == 1) {...} 

candを割り当てる必要はなく、mallocを割り当てる必要がありません。これは不要です。free 0123この関数は、ファイルポインタを返すことになっている

FILE * openFile(char filename[100], char filemode[3]) { 
    FILE *p = fopen(filename, filemode); 
    if (!p) { 
     printf("Error to open %s file. \nThe program will be closed.",filename); 
     exit(1); 
    } 
} 

:の


不要な機能は、より多くのエラーを導入します。また、関数パラメータは、単に const char* filenameconst char *filemodeと書くことができます。例:

FILE * openFile(const char* filename, const char* filemode) { 
    FILE *p = fopen(filename, filemode); 
    if (!p) printf("Error to open %s file. \nThe program will be closed.",filename); 
    return p; 
} 

基本的に役に立たないので、私はこの機能を完全に取り除きます。ちょうどfopenを使用してください。完了したらfcloseでハンドルを閉じてください。


grade[counter].testGrate = testGrade; 
        ^

これは誤植で、それはgrade[counter].testGradeする必要があります。警告レベルを最大に設定するか、少なくともレベル4に設定してプログラムをコンパイルすることをお勧めします。コンパイラはタイプミス、エラー、および警告について通知します。ゼロエラーとゼロ警告でプログラムをコンパイルすることができなければなりません。ここにシンプルなバージョンがあります:

void listAllCandidates(char* candidateFilename) 
{ 
    FILE *fin = fopen(candidateFilename, "rb"); 
    Candidate cand; 
    while(fread(&cand, sizeof(cand), 1, fin)) 
     printf("%s, %s, %d, %f\n", cand.name, cand.document, cand.id, cand.testGrade); 
    fclose(fin); 
} 

int main() 
{ 
    char candidateFilename[] = "file.bin"; 

    FILE *fout = fopen(candidateFilename, "ab"); 
    Candidate cand; 

    strcpy(cand.name, "name1"); 
    strcpy(cand.document, "document1"); 
    cand.id = 1; 
    cand.testGrade = 1.1f; 
    fwrite(&cand, sizeof(cand), 1, fout); 

    strcpy(cand.name, "name2"); 
    strcpy(cand.document, "document2"); 
    cand.id = 2; 
    cand.testGrade = 2.2f; 
    fwrite(&cand, sizeof(cand), 1, fout); 

    fclose(fout); 

    listAllCandidates(candidateFilename); 

    printf("\n"); 
    return 0; 
} 
+0

ありがとうございました。魅力... –