Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 无法在结构数组中正确附加元素_C_Arrays - Fatal编程技术网

C 无法在结构数组中正确附加元素

C 无法在结构数组中正确附加元素,c,arrays,C,Arrays,这是我在这里的第一篇文章。我正在用C语言编写一个程序来处理小丑游戏的结果(这是一个类似Powerball的游戏)。下面我只包括与我的问题相关的代码。首先,向程序输入1,以便它读取以前的结果文件。我将包含该文件,以便您也可以运行它。然后输入3,以便以 id;day/month/year;num1;num2;num3;num4;num5;joker 然后输入99,就可以看到完整的结果数组。 问题是附加到数组(resArr)的前2个结果显示正确,但以下所有附加结果都以伪随机数存储。你知道为什么我的代

这是我在这里的第一篇文章。我正在用C语言编写一个程序来处理小丑游戏的结果(这是一个类似Powerball的游戏)。下面我只包括与我的问题相关的代码。首先,向程序输入1,以便它读取以前的结果文件。我将包含该文件,以便您也可以运行它。然后输入3,以便以

id;day/month/year;num1;num2;num3;num4;num5;joker
然后输入99,就可以看到完整的结果数组。 问题是附加到
数组(resArr)
的前2个结果显示正确,但以下所有附加结果都以伪随机数存储。你知道为什么我的代码只能重复两次吗? 文件:

#包括
#包括
typedef结构结果
{
int-id,date[3],num[5],joker;
}结果;
结果*read()
{
文件*fp=fopen(“joker.csv”,“r”);
结果*temp=(结果*)malloc(sizeof(结果));
结果*result=(结果*)malloc(sizeof(结果));
int i=0,size=1;
而(!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;%d“,&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=(结果*)realloc(结果,(++size)*sizeof(结果));
如果(温度)结果=温度;
其他的
{
结果=空;
打破
}
i++;
}
fclose(fp);
返回结果;
}
int findleength()
{
文件*fp=fopen(“joker.csv”,“r”);
int len,i=0;
而(!feof(fp))
{
char*s=(char*)malloc(50*sizeof(char));
fgets(s,50,fp);
i++;
}
fclose(fp);
len=i-1;
回程透镜;
}
void eisagogi(结果*resArr,int*len)
{
结果结果;
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=(结果*)realloc(resArr,(*len+1)*sizeof(结果));
resArr[*len]=结果;
*len=*len+1;
}
无效显示结果(结果*resArr,内部长度)
{
int i;

对于(i=0;i我将您的
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;
}

您的I/O策略有一部分是脆弱的,另一部分是完全错误的

首先,。正如链接问题的答案所详细解释的,
feof()
函数报告指定流上是否已检测到文件结尾。它无法报告下次尝试读取时是否会遇到EOF,因此您需要在每次读取时注意EOF。在这种情况下,您需要验证
fgets()
是否没有返回NULL,正如@DacSaunders已经建议的那样:

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

(整数文本
0
也用作空指针常量,但我发现使用
null
更清晰)还请注意,Dac将您的
s
更改为自动数组,而不是动态分配。这不仅更易于管理,而且还清除了原始代码因每行动态分配50个字节而出现的内存泄漏,并且从未释放它们。这还允许您使用
sizeof(s)
以获得
s
的容量——这适用于数组,但不适用于指针

第二,您不检查输入

    >P>您应该验证每个代码> FGETSH()/COD>实际上读取一个完整的行(可以通过在数据读取中寻找换行符来确定),因为下一个读取将在最后一个被关闭的地方拾取,并且可以在一条直线的中间。

  • 您应该验证每个
    sscanf()
    实际上是否匹配每个预期字段(通过检查其返回值),因为如果它不匹配,则尝试填充的部分或甚至所有字段都将未初始化。如果输入格式不正确,或者输入行太长,则可能会出现这种故障


额外提示:您还有另一个内存泄漏,即您在声明中为
temp
分配内存,但您从未释放它,甚至也没有使用它。声明指针并不意味着您必须分配内存。

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

你能展示一个程序运行的例子并解释输出与你想要的不同吗?p.s.确保
free()
任何你
malloc()
realloc()的指针
。修复你的问题。答案是为了答案,而不是说谢谢。你可以在对答案的评论中说谢谢。
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
char s[50];
while (fgets(s, sizeof(s), fp) != NULL) {