2017-01-02 8 views
2

これは私の最初の投稿です。私はジョーカーの結果を扱うC言語のプログラムを作っています(Powerballのようなゲームです)。以下に、私の質問に関係するコードだけを示します。まず、前の結果ファイルを読み込むようにプログラムに1を入力します。あなたが入力99その後構造体配列に要素を正しく追加できません

id;day/month/year;num1;num2;num3;num4;num5;joker 

の形で結果を挿入して、完全な結果の配列が表示されるように、あなたが入力3 well.Afterwardsとして、それを実行できるように、私は、ファイルが含まれます。 問題は、array(resArr)に追加された最初の2つの結果は正しく表示されますが、次のすべての追加は擬似乱数で保存されることです。私のコードが2回だけ繰り返される理由は何ですか? ファイル:link

#include <stdio.h> 
#include <stdlib.h> 

typedef struct results 
{ 
    int id,date[3],num[5],joker; 
}Results; 

Results *read() 
{ 
    FILE *fp=fopen("joker.csv","r"); 
    Results *temp=(Results *)malloc(sizeof(Results)); 
    Results *result=(Results *)malloc(sizeof(Results)); 
    int i=0,size=1; 
    while(!feof(fp)) 
    { 
     char *s=(char *)malloc(50*sizeof(char)); 
     fgets(s,50,fp); 
sscanf(s,"%d;%d/%d/%d;%d;%d;%d;%d;%d;%d",&result[i].id,&result[i].date[0],&result[i].date[1],&result[i].date[2],&result[i].num[0],&result[i].num[1],&result[i].num[2],&result[i].num[3],&result[i].num[4],&result[i].joker); 
     temp=(Results *)realloc(result,(++size)*sizeof(Results)); 
     if (temp) result=temp; 
     else 
     { 
      result=NULL; 
      break; 
     } 
     i++; 
    } 
    fclose(fp); 
    return result; 
} 

int findLength() 
{ 
    FILE *fp=fopen("joker.csv","r"); 
    int len,i=0; 
    while(!feof(fp)) 
    { 
     char *s=(char *)malloc(50*sizeof(char)); 
     fgets(s,50,fp); 
     i++; 
    } 
    fclose(fp); 
    len=i-1; 
    return len; 
} 

void eisagogi(Results *resArr,int *len) 
{ 
    Results result; 
    printf("id;dd/mm/yyyy;num1;num2;num3;num4;num5;joker\n"); 
scanf("%d;%d/%d/%d;%d;%d;%d;%d;%d;%d",&result.id,&result.date[0],&result.date[1],&result.date[2],&result.num[0],&result.num[1],&result.num[2],&result.num[3],&result.num[4],&result.joker); 
    resArr=(Results *)realloc(resArr,(*len+1)*sizeof(Results)); 
    resArr[*len]=result; 
    *len=*len+1; 
} 

void showResults(Results *resArr,int len) 
{ 
    int i; 
    for (i=0;i<len;i++) 
    {  printf("%d;%d/%d/%d;%d;%d;%d;%d;%d;%d\n",resArr[i].id,resArr[i].date[0],resArr[i].date[1],resArr[i].date[2],resArr[i].num[0],resArr[i].num[1],resArr[i].num[2],resArr[i].num[3],resArr[i].num[4],resArr[i].joker); 
    } 
} 

int menuChoose() 
{ 
    int choice; 
    printf("Load results 1\n"); 
    printf("Append result 3\n"); 
    printf("Result array 99\n"); 
    printf("Exit 0\n"); 
    scanf("%d",&choice); 
    return choice; 
} 

int main() 
{ 
    Results *resArr=(Results *)malloc(sizeof(Results)); 
    int choice,len; 
    while(1) 
    { 
     choice=menuChoose(); 
     switch(choice) 
     { 
     case 1: 
      resArr=read(); 
      len=findLength(); 
      break; 
     case 3: 
      eisagogi(resArr,&len); 
      break; 
     case 99: 
      showResults(resArr,len); 
      break; 
     case 0: 
      exit(0); 
      break; 
     } 
    } 
    return 0; 
} 
+0

プログラムの実行例を示し、出力があなたの望むものとどのように異なるかを説明できますか? –

+0

p.s.あなたは 'malloc()'や 'realloc()'のポインタを 'free()'してください。 –

+4

あなたの[feof()の使用](http://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong)を修正してください。 –

答えて

3

私はあなたのfeof

fgetsから
char s[50]; 
while (fgets(s, sizeof(s), fp) != 0) { 

を変更し、今ではあなたが3件の結果を追加し、それらを表示することができているようです。

#include <stdio.h> 
#include <stdlib.h> 

typedef struct results { 
    int id, date[3], num[5], joker; 
} Results; 

Results *read() { 
    FILE *fp = fopen("joker.csv", "r"); 
    Results *temp = (Results *) malloc(sizeof(Results)); 
    Results *result = (Results *) malloc(sizeof(Results)); 
    int i = 0, size = 1; 
    char s[50]; 
    while (fgets(s, sizeof(s), fp) != 0) { 
     sscanf(s, "%d;%d/%d/%d;%d;%d;%d;%d;%d;%d", &result[i].id, &result[i].date[0], &result[i].date[1], 
       &result[i].date[2], &result[i].num[0], &result[i].num[1], &result[i].num[2], &result[i].num[3], 
       &result[i].num[4], &result[i].joker); 
     temp = (Results *) realloc(result, (++size) * sizeof(Results)); 
     if (temp) result = temp; 
     else { 
      result = NULL; 
      break; 
     } 
     i++; 
    } 
    fclose(fp); 
    return result; 
} 

int findLength() { 
    FILE *fp = fopen("joker.csv", "r"); 
    int len, i = 0; 
    while (!feof(fp)) { 
     char *s = (char *) malloc(50 * sizeof(char)); 
     fgets(s, 50, fp); 
     i++; 
    } 
    fclose(fp); 
    len = i - 1; 
    return len; 
} 

void eisagogi(Results *resArr, int *len) { 
    Results result; 
    printf("id;dd/mm/yyyy;num1;num2;num3;num4;num5;joker\n"); 
    scanf("%d;%d/%d/%d;%d;%d;%d;%d;%d;%d", &result.id, &result.date[0], &result.date[1], &result.date[2], 
      &result.num[0], &result.num[1], &result.num[2], &result.num[3], &result.num[4], &result.joker); 
    resArr = (Results *) realloc(resArr, (*len + 1) * sizeof(Results)); 
    resArr[*len] = result; 
    *len = *len + 1; 
} 

void showResults(Results *resArr, int len) { 
    int i; 
    for (i = 0; i < len; i++) { 
     printf("%d;%d/%d/%d;%d;%d;%d;%d;%d;%d\n", resArr[i].id, resArr[i].date[0], resArr[i].date[1], resArr[i].date[2], 
       resArr[i].num[0], resArr[i].num[1], resArr[i].num[2], resArr[i].num[3], resArr[i].num[4], 
       resArr[i].joker); 
    } 
} 

int menuChoose() { 
    int choice; 
    printf("Load results 1\n"); 
    printf("Append result 3\n"); 
    printf("Result array 99\n"); 
    printf("Exit 0\n"); 
    scanf("%d", &choice); 
    return choice; 
} 

int main() { 
    Results *resArr = (Results *) malloc(sizeof(Results)); 
    int choice, len; 
    while (1) { 
     choice = menuChoose(); 
     switch (choice) { 
      case 1: 
       resArr = read(); 
       len = findLength(); 
       break; 
      case 3: 
       eisagogi(resArr, &len); 
       break; 
      case 99: 
       showResults(resArr, len); 
       break; 
      case 0: 
       exit(0); 
       break; 
     } 
    } 
    return 0; 
} 

テスト

Load results 1 
Append result 3 
Result array 99 
Exit 0 
3 
id;dd/mm/yyyy;num1;num2;num3;num4;num5;joker 
1768;18/12/2016;11;28;5;9;31;1 
Load results 1 
Append result 3 
Result array 99 
Exit 0 
3 
id;dd/mm/yyyy;num1;num2;num3;num4;num5;joker 
1769;18/12/2016;11;28;5;9;31;2 
Load results 1 
Append result 3 
Result array 99 
Exit 0 
3 
id;dd/mm/yyyy;num1;num2;num3;num4;num5;joker 
1770;18/12/2016;11;28;5;9;31;3 
Load results 1 
Append result 3 
Result array 99 
Exit 0 
1 
... 
1768;18/12/2016;11;28;5;9;31;1 
1769;18/12/2016;11;28;5;9;31;2 
1770;18/12/2016;11;28;5;9;31;3 
Load results 1 
Append result 3 
Result array 99 
Exit 0 
1

あなたのI/O戦略が一部壊れやすいと一部フラット間違っています。

最初は、while(!feof(fp)) is always wrongです。リンクされた質問に対する回答が詳細に説明されているので、feof()関数は、指定されたストリーム上でファイルの終わりがすでに検出されているかどうかを報告します。それは、次の読み込み試行がEOFに遭遇するかどうかを報告することができないので、各読み込み時にそれを監視する必要があります。この場合、あなたは@DacSaundersが既に推奨されているようfgets()は、NULLを返さないことを確認するとよいでしょう:

char s[50]; 
while (fgets(s, sizeof(s), fp) != NULL) { 

...

を(0整数リテラルはまた、NULLポインタ定数として機能しますが、私はNULLを使うのがはっきりしています。)Dacはあなたのsを動的に割り当てずに自動配列に変更しました。これは管理が容易なだけでなく、各行に50バイトを動的に割り当て、元のコードを解放することなく、元のコードが示したメモリリークを解決します。これにより、sizeof(s)を使用してsの容量を取得することもできます。これは配列に対しては機能しますが、ポインタに対しては機能しません。

第2位では、入力を確認しません。

  • あなたは最後に中断したところ、次の読み取りをピックアップしますため、実際には各fgets()は、行全体を(データの読み出しで改行を探すことによって決定することができるよう)を読み取ることを確認する必要があり、それはラインの途中にある可能性があります。あなたはそれがそうしないならば、あなたが移入しようとしているフィールドの一部あるいはすべてが初期化されていないことになるため、実際には各sscanf()は、(その戻り値をチェックすることによって)すべての期待される分野と一致していることを確認する必要があり

  • 。入力が不正な場合、または入力行が長すぎる場合でも、このようなエラーが発生する可能性があります。

ボーナスチップは:あなたは別のメモリリークを持っている、という点で、あなたはその宣言にtempためのメモリを割り当てるが、あなたはそれを解放することはありません、またしても、それを使用しています。ポインタを宣言しても、メモリを割り当てる必要はありません。

0

ありがとうございます!私はfindLengthのDacの変更を繰り返しました。また、temp()を使ってread()を一時的にフリーズしました。 メモリリークのためにこのバグは起こっていましたか?

+0

答えは答えのためのものであり、感謝の言葉ではありません。あなたは答えに対するコメントで感謝することができます。 –

関連する問題