我尝试在每个循环中使用realloc()
,所以我只为我的int
数组使用了必要的内存,但是输出值发生了变化。尽管如此,当我在代码中使用Valgrind时,我得到了正确的值。
我在做Advent of Code 2022的第一天
输入文件是一个.txt文件,如下所示:
7569
1357
10134
4696
4423
8869
3562
6597
4038
9038
1352
8005
4811
6281
3961
4023
7234
3510
7728
1569
4583
7495
3941
6015
6531
2637
我试图对数字求和并将其存储在数组中的特定索引中,如果有空行,则增加索引。
给定该示例输入,它应该如下所示:
elf [0] = 47207
elf [1] = 41509
elf [2] = 51243
我得到的是:
elf [245] = 63138
elf [246] = 181168
elf [247] = 41570
elf [248] = 36264
elf [249] = 59089
elf [250] = 185061
我想要的(结果使用valgrind):
elf [245] = 63138
elf [246] = 52399
elf [247] = 41570
elf [248] = 36264
elf [249] = 59089
elf [250] = 56308
我的代码:
int *read_calories(char *filename)
{
FILE *fp = fopen(filename, "r");
char *line = NULL;
int i = 0;
size_t len = 0;
ssize_t nread;
struct stat size;
stat(filename, &size);
int tab_size = 1;
int *calories = malloc(sizeof(int) * 2);
if (fp == NULL)
{
perror("Can't open file\n");
exit(EXIT_FAILURE);
}
while ((nread = getline(&line, &len, fp)) != -1)
{
if (nread == 1) {
i++;
++tab_size;
calories = realloc(calories, tab_size * sizeof(int));
} else {
calories[i] += atoi(line);
}
}
calories[i + 1] = '\0';
free(line);
fclose(fp);
return calories;
}
int main()
{
int *calories = read_calories("input.txt");
for (int i = 0; calories[i] != '\0'; i++) {
printf("elf [%d] = %d \n", i, calories[i]);
}
free(calories);
return 0;
}
1条答案
按热度按时间zf9nrax11#
你的卡路里阅读代码有一些不错的东西,但是很混乱。由
malloc()
分配的数据没有归零,所以在calories[i] += atoi(line);
中使用+=
是不好的。你没有显示输入数据的格式。不清楚是必须读取一串数字直到一个空行,然后将总和存储在数组中(然后冲洗并重复到EOF),还是只需要从文件中读取数字并将它们存储到数组中。
每一行都有一个单独存储的编号
下面的代码假设每一行都包含一个应该存储在数组中的数字。适应另一种处理方式并不困难。
我对
perror()
不感兴趣--它确实很简单,但要从中得到好的信息相对来说比较困难。代码确保数组中有一个额外的条目,用于结尾处的零条目。然而,它不会发现数组中间的零条目。这通常是由于atoi()
无法转换值造成的。我生成了一个
input.txt
文件,其中包含10个介于100和1000之间的随机值:程序的输出为:
要求和的数字块,由空行分隔
这段代码与前面的答案非常接近,但是“add to the array”代码被提取到一个函数中,因此可以使用两次。使用一个结构来封装数组细节可能会更好。我可能还应该使用
size_t
而不是int
来表示大小。修订后的数据文件:
(Note结尾没有空行!)
输出量:
交叉检查结果的Awk脚本:
结果: