2d array and fwrite and fread

This is a discussion on 2d array and fwrite and fread within the C Programming forums, part of the General Programming Boards category; Hi! I've been looking for working code example that uses 2d arrays with fwrite and fread but haven't found any. ...

  1. #1
    Registered User
    Join Date
    Nov 2008
    Posts
    19

    2d array and fwrite and fread

    Hi! I've been looking for working code example that uses 2d arrays with fwrite and fread but haven't found any. So I tried to realize it myself but I cannot get it work. The goal is to make 2d array according to the given size, for example 10x10 and then to write these values into file and afterwards to read these values by using fread. I don't know if save_table function works correctly, because get_table_size returns 0 although it should return 10 because test program makes 10x10 table. Any ideas?

    Code:
    int multiply(int x, int y)
    {
    return x*y;
    }
    
    int add(int x, int y)
    {
    return x+y;
    }
    
    int ** create_table(int size, int (* oper) (int, int))
    {
        int x;
        int y;
        int **2darray;
        2darray = malloc (size*sizeof(int*));
    
        for(x = 0; x < size; x++)
        {
    		2darray[x] = (int*)malloc(sizeof(int)*size);
    	for(y=0;y<size;y++)
            {
    		2darray[x][y]=(* oper)(x,y);
    	}
        }
         return 2darray;
    }
    
    int save_table(FILE * fp, int ** table, int size)
    {
        int x=0;
        if(fp==NULL)
        {
    	    return 0;
        } else {
         for(x;x < size;x++)
                fwrite(table[x],sizeof(int),size,fp);     
    }
         return 1;        
    }
    
    int get_table_size(FILE *file)
    { 
          int nitems;
        
          if(file==NULL) 
                return 1
          fread(&nitems,sizeof(int),1,file);
          
          return nitems;
    }
    Last edited by totalnewbie; 01-09-2009 at 02:32 AM.

  2. #2
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,556
    But you never write the size of the array to the file! How can it then read it later?
    And you seriously need to indent the code.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  3. #3
    Registered User
    Join Date
    Nov 2008
    Posts
    19
    Quote Originally Posted by Elysia View Post
    But you never write the size of the array to the file! How can it then read it later?
    And you seriously need to indent the code.
    Code:
    fread(&nitems,sizeof(int),1,file);
    returns the number of lines as I've read from different sites.
    I don't know how fwrite and fread behaves with 2d arrays, how it distinguishes between x and y. Using fprintf I can use for example '\n' and when reading data back with fread I can tokenize. But the last one is not my goal. I just want to make as short and effective code as possible.

  4. #4
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,556
    That's the read - where's the write?
    Understand that fwrite doesn't care what data it takes - it just dumps it right out. It does not care if it's a string, or an integer, or whatever. It writes as many bytes as you tell it to do, period.
    It's your responsibility to write the array. Just feed it the individual pointers and size.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  5. #5
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Since this line:
    Code:
        int **2darray;
    prevents the code from compiling, can we assume that the code you have posted is not actually the code you are using? And as such, we do not know if this code is correct in any other way either?

    But Elysia has it right - you are not writing out how large the data is, so how would you expect to be able to read it back?

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  6. #6
    Registered User
    Join Date
    Nov 2008
    Posts
    19
    Quote Originally Posted by Elysia View Post
    That's the read - where's the write?
    Understand that fwrite doesn't care what data it takes - it just dumps it right out. It does not care if it's a string, or an integer, or whatever. It writes as many bytes as you tell it to do, period.
    It's your responsibility to write the array. Just feed it the individual pointers and size.
    That's the write:
    Code:
    fwrite(table[x],sizeof(int),size,fp);

  7. #7
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,556
    That writes the array, does it not? Not the size.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  8. #8
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    I think what the problem here is that totalnewbie doesn't understand what gets stored in the file.

    When you use fwrite(), it will write nitems * itemsize bytes of data. It doesn't store the size of such a write in any way. It is exactly the same thing to loop through nitmes times and use 1 as nitems, as it is to do one fwrite with a nitems written all in one go.

    So if you want to store the size in the file, you will need a separate fwrite() to store that. Or you could, perhaps, examine the size of the file and figure out what the actual size is [this works if the size is always symmetrical, e.g. a square or rectangle with known proportions of the sides - it won't work if it's equally legal to have a 10 x 1 or 2 x 5 or 5 x 2 or 1 x 10 array stored in the file, in that case you would need to store both x and y dimensions (well, you could store just one and determine the other from that, but it's just extra work to do that - and saving 4 bytes is probably not worth the extra effort)].

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  9. #9
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,556
    That pretty much sums up what I said. Fwrite only writes whatever data you pass it. It parses the data as "raw" data, not as types and just dumps it to the disk.
    It does not care if it's an integer, a string or whatever. Since it does not know the data, it does not write the size.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  10. #10
    Registered User
    Join Date
    Nov 2008
    Posts
    19
    I have that example: http://www.daniweb.com/forums/thread52253.html but I cannot find anything like that about multidimensional array. I've been looking for multidimensional example but haven't found. That's the way I learn new things - experimenting with working examples.

  11. #11
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,556
    It works the same for a multi-dimensional array allocated on the stack.
    For dynamically allocated arrays, you must store the size and write each element separately because they are not adjacent to each other in memory. Plus you must know how much memory to allocate beforehand before you read it back. Unless, of course, the size is static (always the same).
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  12. #12
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    There is absolutely no difference between writing a 2D array and 1D arrays (or any other data) - except a complication in your case is that your array is dynamically allocated, so you can't write it as one big lump - you have to write a row at a time, as that is how the memory is allocated.

    However, when you read your data back, you either need to know it's size by implication (e.g. you know the applicatikn writes a 100 x 100 matrix, so you read 100 x 100 matrix bac) or you need to STORE the size within the file when you write the file (or use the size of the file to figure out the size of the content). Your current code is NOT storing the size of the array, so you are not able to read that information from the file.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  13. #13
    Registered User
    Join Date
    Nov 2008
    Posts
    19
    Quote Originally Posted by Elysia View Post
    It works the same for a multi-dimensional array allocated on the stack.
    For dynamically allocated arrays, you must store the size and write each element separately because they are not adjacent to each other in memory. Plus you must know how much memory to allocate beforehand before you read it back. Unless, of course, the size is static (always the same).
    Ok, just tell me wheter I am riht or not.
    1. If I make 10x10 table (dynamic array) then all of these memory cells are side by side and figuratively speaking the beginning of the memory cell number is 1 and the end of the memory cell is 100. For my case the size of the array is given only once and it wouldn't be changed during the program runtime.
    2. To read the size of the array afterwards I think to add one element to the array for storing the size. As for my case the first one is the size and the elements from 2 to 101 are values.
    3. For fwrite I look it's size up int the first array cell, then I do the array for that size and then I read all of these values from the file by using fwrite into the array.

    That's the idea how I try to realize this program now. Does it work?

  14. #14
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,556
    Quote Originally Posted by totalnewbie View Post
    Ok, just tell me wheter I am riht or not.
    1. If I make 10x10 table (dynamic array) then all of these memory cells are side by side and figuratively speaking the beginning of the memory cell number is 1 and the end of the memory cell is 100. For my case the size of the array is given only once and it wouldn't be changed during the program runtime.
    As was explained to you, no they are not.
    Your dynamic 2D array works by defining an array of pointers, and then allocating memory and store their address in those pointers.
    That memory is not adjacent!
    Each call to malloc is not guaranteed to be side-by-side.

    2. To read the size of the array afterwards I think to add one element to the array for storing the size. As for my case the first one is the size and the elements from 2 to 101 are values.
    No. Why would you need to do that?
    You can issue two writes and two reads.
    The first writes the size. The second writes the data.
    And vice versa.

    3. For fwrite I look it's size up int the first array cell, then I do the array for that size and then I read all of these values from the file by using fwrite into the array.
    I have no idea what that just meant, but as I explained above. Write size first, then the array. Similarly, read the size first, allocate, read the array.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  15. #15
    Registered User
    Join Date
    Nov 2008
    Posts
    19
    I am getting the error: "glibc detected malloc(): memory corruption: 0xb7fd3008" when function int ** load_table(FILE * file, int size) starts under UNIX. It works nicely under Windows.

    Code:
    #include "mathalizer.h"
    
    int multiply(int x, int y)
    {
        return x*y;
    }
    
    int add(int x, int y)
    {
        return x+y;
    }
    
    int ** create_table(int size, int (* oper) (int,int))
    {
        int x; 
        int y; 
        int **array;
        if(size<1) return NULL;
        array = (int **)malloc(size*sizeof(int*));
        if(array==NULL) return 1;
    
        for(x=0;x<size;x++)
        {
            array[x]=(int*)malloc(size*sizeof(int));
        }
        
        for(x=0;x<size;x++) 
        {
            for(y=0;y<size;y++)
            {
                array[x][y]=(* oper)(x,y);
            }      
        }
    	
        return array;
    }
    
    int save_table(FILE * fp, int ** array, int size)
    {
        int x;
        
        for(x=0;x<size;x++)
        {
            fwrite(array[x],sizeof(int),size,fp);     
        }
        fclose (fp);
       
        return 1;        
    }
    
    int ** load_table(FILE * file, int size)
    {
        int x;
        int fread_return_code_2;
        int **array2;
        array2 = (int **)malloc(size*sizeof(int*));
        if(array2==NULL) return 1;
    
        for(x=0;x<size;x++)
        {
            array2[x]=(int*)malloc(size*sizeof(int));
        }
    	
        for(x=0;x<size;x++)
        {
            fread_return_code_2=fread(array2[x],sizeof(int),size,file);
        }
        if(fread_return_code_2!=size) return 1;
        fclose(file);
    	
        return array2;
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Image Processing Help Required
    By dantu1985 in forum C Programming
    Replies: 7
    Last Post: 12-31-2007, 08:30 AM
  2. array of structures help!
    By voodoo3182 in forum C Programming
    Replies: 12
    Last Post: 08-03-2005, 02:58 PM
  3. array of pointers to structs
    By stumon in forum C Programming
    Replies: 7
    Last Post: 03-24-2003, 06:13 AM
  4. Saving array of structs to file
    By |deep| in forum C++ Programming
    Replies: 2
    Last Post: 06-01-2002, 08:14 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21