1

我正在尝试从文件中读取结构,然后显示(和排序)和数组。我遇到了麻烦,但我认为这与我没有访问正确的内存有关。当我打印数组时,它会出现大量随机数。

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;
}
4

2 回答 2

1

您的结构的大小仅包括数组的最小分配(我认为是一个条目)。它实际上并没有为您想要的 200 个条目分配足够的空间。有一些可能的修复。

如果总是 200 个条目,那么只需将建筑物声明为大小为 200。这是最简单的。

如果您在阅读之前知道条目数,那么您可以做一些不愉快的事情,例如(s 是条目数):

struct details *data1 = (struct details *) malloc(sizeof(struct details)+s*sizeof(int));

完成后免费数据1。这种类型的代码通常不受欢迎,但过去很常见。读取命令也变得复杂。

最后的选择是将建筑物更改为 int*,然后在读取之前对该数组进行 m​​alloc。同样,读取必须在循环中完成。

于 2012-12-11T21:30:57.123 回答
0

您有两个问题不利于您打印数据。

  • 没有为记录分配足够的空间。
  • 没有为记录读取足够的数据。

该行struct details data1仅在堆栈上为struct. 你需要足够的 200 个。我会立即建议一个数组。

struct details data1[200];

当您执行读取时fread(&data1, structSize, 1, fp),您只会读取一条大小为 的记录structSize。现在您已经分配了足够的内存来读取 200 条记录,您也可以将正在读取的记录数增加到 200 条。

fread(data1, structSize, 200, fp);

(请注意,我们删除了 ,&因为我们现在正在处理一个数组。如果您只是按名称引用它们,数组会自动返回它们的基地址。)

现在,如果您的文件中没有 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例程中),您很可能会出现段错误,并且您的程序将永远无法运行。尝试为此发布通用解决方案有点超出我的回答范围。可以这么说,您要么必须使用固定大小的数组,要么将可变大小的数组动态写入磁盘(可变长度记录)。固定大小的数组会容易得多。如果我们将您的定义更改为以下内容,我们将从磁盘加载一些数据。

struct details{
    int numberOfPresents;
    int numberOfBuildings;
    int buildings[16];
};

我们也会避免 seg-faulting,这是一个很好的加分项。但是,我不知道您的输入文件是什么样的,所以我不知道这是否会根据您的数据起作用。

于 2012-12-11T21:29:01.590 回答