无法正确附加struct数组中的元素

时间:2017-01-02 13:58:31

标签: c arrays

这是我在这里的第一篇文章。我正在C中制作一个处理Joker结果的程序(它是一个类似Powerball的游戏)。下面我只包含对我的问题很重要的代码。首先,输入1到程序,以便它读取以前的结果文件。我将包含该文件,以便您也可以运行它。之后输入3,以便以

的形式插入结果
id;day/month/year;num1;num2;num3;num4;num5;joker

之后输入99,你会看到完整的结果数组。 问题是附加到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;
}

3 个答案:

答案 0 :(得分:3)

我将您的libraryDependencies += "org.seleniumhq.selenium" % "selenium-java" % "3.0.1" libraryDependencies += "net.lightbody.bmp" % "browsermob-core" % "2.1.2" 更改为$ phantomjs --version 2.0.1-development $ phantomjs --version 2.1.1

feof

现在看来你可以添加3个结果并显示它们。

fgets

测试

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

答案 1 :(得分: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分配了内存,但您永远不会释放它,甚至不会使用它。仅仅因为你声明一个指针并不意味着你必须分配内存。

答案 2 :(得分:0)

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