从C中的结构打印int数组

时间:2012-12-11 21:17:39

标签: c

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

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

2 个答案:

答案 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,这是一个很好的加分。但是,我不知道您的输入文件是什么样的,所以我不知道这是否适用于您的数据。