我试图从文件读取结构,然后显示(和排序)和数组。我遇到了麻烦,我认为这与我没有访问正确的内存有关。当我打印数组时,它会出现随机数。
struct details
{
int numberOfPresents;
int numberOfBuildings;
int buildings[];
};
void print_int_array(const int *array)
{
for(int i=0; i<200; i++)
printf("%d | ", array[i]);
putchar('\n');
}
void sort(int buildings[], int count)
{
int i, j, temp;
do {
j = 0;
for (i = 0;i<count-1;i++)
{
if (buildings[i] < buildings[i+1])
{
j = 1;
temp = buildings[i];
buildings[i] = buildings[i+1];
buildings[i+1] = temp;
}
}
} while (j == 1);
}
int main()
{
FILE *fp;
fp = fopen("buildings.out", "r");
struct details data1;
size_t structSize = sizeof(struct details);
//size_t arraySize = sizeof(int)*sizeof(buildings);
fread(&data1, structSize, 1, fp);
for(int i=0; i<200; i++)
printf("%d | ", data1.buildings[i]);
//sort(data1.buildings );
//print_int_array(data1.buildings, arraySize);
//printf("Number of Houses: %d\n",numberOfHouses(data1.numberOfPresents, data1.buildings));
fclose(fp);
return 0;
}
答案 0 :(得分:1)
你的struct的size只包含一个最小的数组分配(我认为一个条目)。它实际上并没有为您想要的200个条目分配足够的内容。有一些可能的修复。
如果它总是200个条目,那么只需将建筑物声明为大小为200.这是最简单的。
如果您在阅读之前知道了条目数,那么您可以做一些不愉快的事情(s是条目数):
struct details *data1 = (struct details *) malloc(sizeof(struct details)+s*sizeof(int));
完成后和免费数据1。这类代码通常不受欢迎,但过去很常见。 read命令也变得复杂。
最后一个选项是在阅读之前将建筑物更改为int *,然后将malloc更改为该数组。同样,读取必须在循环中完成。
答案 1 :(得分:0)
你有两个问题不利于你打印数据。
行struct details data1
仅在堆栈上为struct
的一个副本分配足够的空间。你需要足够200个。我马上就建议一个阵列。
struct details data1[200];
当您执行阅读fread(&data1, structSize, 1, fp)
时,您只能阅读一个大小为structSize
的记录。现在您已经分配了足够的内存来读取200条记录,您可以将您正在读取的记录数增加到200条。
fread(data1, structSize, 200, fp);
(注意我们删除了&
,因为我们现在正在处理一个数组。如果你只是按名称引用它们,Arrays会自动返回它们的基址。)
现在,如果您的文件中没有200条记录,该怎么办?您可能需要捕获fread()
的返回值以确定实际读取的记录数。
int intNumberOfRecords = fread(&data1, structSize, 200, fp);
for(int i=0; i<intNumberOfRecords ; i++)
[...]
现在我们已经开始工作了,我们可以近距离地了解srtuct
本身。对于我们无法轻易克服的定义,我们遇到了挑战。
struct details{
int numberOfPresents;
int numberOfBuildings;
int buildings[];
};
最后一个成员buildings[]
无法从文件中正确读取。这是因为在32位内存模型中,它只是一个32位整数。换句话说,您将从磁盘读取的内容只是一个32位数字,指向内存中的某个位置。你最不会得到的是一个包含建筑物的阵列。如果您尝试访问它(即在sort
例行程序中),您很可能会出现seg-fault,并且您的程序将无法运行。试图为此发布一般解决方案有点超出我的答案范围。可以这么说,你要么必须使用固定大小的数组,要么将可变大小的数组动态写入磁盘(可变长度记录)。固定大小的数组会容易得多。如果我们将您的定义更改为以下内容,我们将从磁盘加载一些数据。
struct details{
int numberOfPresents;
int numberOfBuildings;
int buildings[16];
};
我们也避免了seg-faulting,这是一个很好的加分。但是,我不知道您的输入文件是什么样的,所以我不知道这是否适用于您的数据。