2017-01-02 57 views
2

这是我第一篇文章。我正在用C处理一个处理Joker结果的程序(这是一个类似Powerball的游戏)。下面我只包括对我的问题很重要的代码。首先,你输入1到程序中,以便它读取以前的结果文件。我将包括文件,这样就可以让你在无法正确追加结构数组中的元素

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

形式插入结果之后,你输入99,你看到完整的结果阵列well.Afterwards运行它,你输入3。 问题是正确显示了附加到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.一定要free()''你的'malloc()'或'realloc()'指针。 –

+4

修复你的[使用feof()](http://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong)。 –

回答

3

我改变了你的feoffgets

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,因此您需要在每次阅读时注意这一点。在这种情况下,你会想验证fgets()不返回NULL,因为@DacSaunders已经推荐:

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

...

(整数字面0也作为一个空指针常数,但我发现它更清晰地使用NULL。)还请注意,Dac已将s更改为自动数组,而不是将其动态分配。这不仅更容易管理,而且它清除了原始代码展示的内存泄漏,从每条线路动态分配50个字节开始,永远不会释放它们。这也可以让你使用sizeof(s)来获得s的容量 - 适用于数组,但不适用于指针。

第二,你不检查你的输入。

  • 您应该验证其实每个fgets()读一整行(如可通过寻找在数据读取方面换行符确定),以进行下一读取将拿起其中最后一个离开,这可能在一条线的中间。

  • 您应该验证其实每个sscanf()每一个所需字段匹配(通过检查其返回值),因为如果不这样做的那么一些,甚至你试图填充将是未初始化的字段。如果输入格式错误,或者输入行太长,您可能会遇到这样的失败。

特别提示:您有另一个内存泄漏,在您为在其声明中temp分配内存,但你永远不自由的,甚至也没有使用它。仅仅因为你声明了一个指针并不意味着你必须分配内存。

0

非常感谢!我在findLength中重复了Dac的变化,并且我还使用temp()来释放read()中的temp。 这个错误是由于内存泄漏而发生的吗?

+0

答案是答案,而不是说谢谢。你可以在评论中对答案表示感谢。 –