-1

I am facing a problem with storing arrays in structures, which are further written onto a file.

  1. The arrays are square matrices.
  2. The arrays and the size n are stored in a structure. This structure is then stored in a file(binary file).
  3. The size of this array is subject to input from the user during the run time.
  4. Whenever I read the structure from the file in the future, I want to recover all those elements which were saved as they were(I suspect that is why saving the array as int **a has not worked).

The problem is that the size of matrix can be variable and is subject to user's choice(which is, by the way, also stored in the structure and further onto file). I acknowledge that I can take the size of array to be large enough to accommodate any possible value of size, but that would be a wastage of space. Further if I write every element of the array individually then it would be rather a hassle to handle each value individually. Reading a structure is better than reading many values individually. Of course, if I do this:

struct attribs
{
    int a[n][n], b[n][n], n;
}

then it doesn't work. Is there a smarter way around my problem? As for present I take a[][] and b[][] to be of size 20X20 each, while expected value is 4X4 to 9X9, and store the actual value in n so that only that part can be read easily when the structure is read.

Sukhmeet Singh
  • 29
  • 1
  • 11
  • I don't understand why you just don't allocate the array dynamically using malloc ? – OopsUser Jul 22 '14 at 12:40
  • Did that @OopsUser but the data, you see, doesn't remain intact on next read of the structure. – Sukhmeet Singh Jul 22 '14 at 12:44
  • I don't seem to understand the big picture. – OopsUser Jul 22 '14 at 13:01
  • @Oopsuser I am just asking (and am not sure, and am just a beginner) that if we store a pointer to the array elements in the file, as you say, will the array, with all its elements (as they were when pointer was stored) be read as it is, when I read it on the next execution of my program? To be very clear, the array elements need to be stored in a file. – Sukhmeet Singh Jul 22 '14 at 13:05
  • What it the overall goal you are trying to achieve ? reading array from file ? – OopsUser Jul 22 '14 at 13:13
  • yes sir thats what my goal is. – Sukhmeet Singh Jul 22 '14 at 13:15
  • 1
    Can you elaborate on that ? is it just a file with comma separated int's ? how do you know how many columns and rows are in this 2 dimensional array ? can you add to your question the content of the file ? – OopsUser Jul 22 '14 at 20:02
  • The answer depends upon the save format. The easiest save format would be a number first, telling you to allocate a 2-D array of `n`×`n` elements, where `n` is the number you read. That also allows you to know how many items to read and where to store them. The hard way would be to use a variable-length format, where you must read the entire first row (`matrix[0][0]` to `matrix[0][n - 1]`) to determine how many items to allocate. –  Jul 23 '14 at 02:03
  • I have clearly mentioned that @OopsUser that it is a file containing structures, I have to read them and recover the elements of the arrays they contain. Still I have edited further to make it more clear. – Sukhmeet Singh Jul 23 '14 at 10:18

3 Answers3

1

You cannot have a variable length array as a member of a structure type. What you can do is use a flexible array member as the last member of a structure type. See c99, 6.7.2.1 for more information on flexible array member feature.

In your case, I think the best way is to use pointer members in your structure type and allocate the array objects through malloc.

ouah
  • 142,963
  • 15
  • 272
  • 331
1

You can write as follows If you are using GCC.

int size;
scanf("%d", &size);
typedef int mat[size][size];
struct attribs {
    mat a, b;
    int n;
};
struct attribs x;//Note that you can not create large arrays on the stack
x.n = size;
//do something
//x.a[row_index][col_index]=value;

Created in dynamic memory using a pointer.

#include <stdio.h>
#include <stdlib.h>

struct attribs {
    void *a, *b;
    int n;
};

int main (int argc, char *argv[]) {
    int size;
    scanf("%d", &size);
    struct attribs x;
    x.n = size;
    x.a = malloc(sizeof(int[size][size]));
    x.b = malloc(sizeof(int[size][size]));
    int (*mat)[size][size] = x.a;
    (*mat)[3][3] = 15;
    printf("%d\n", (*mat)[3][3]);
    free(x.a); free(x.b);
    return 0;
}
BLUEPIXY
  • 39,699
  • 7
  • 33
  • 70
1

When you write the structure to the file, where the lengths are subject to user's preferences, you should write the size first, then the contents of each array. Then to dynamically re-create the matrix, you need only read the size, allocate the appropriate memory, and read the values.

How you separate matrix a from matrix b is up to you, but your example shows they are the same size. That suggests that after you read n×n integers into a, you can start reading the saved values of b, assuming you didn't write any possible padding bytes that might exist between a and b (write the size, a, and b separately instead of writing the entire structure at once to avoid padding bytes).

If you cannot alter the format, and the values are all stored together as a jumble of bytes, you must unfortunately read blindly, storing every value. The last sizeof(int) bytes will be the size, again assuming there are no padding bytes.

If possible, save yourself a lot of trouble and write the size first, followed by matrix a, then matrix b.

Of course, since the matrix is dynamically sized, perhaps you allocated an array of pointers dynamically first, then an array of ints for each. In that case, unless you looped through each element of a (a[0], a[1], ...), you wrote the pointers to the file instead of the values they pointed to.