Thread: Files, Structs, and Pointers

  1. #1
    Registered User
    Join Date
    Feb 2005
    Posts
    11

    Files, Structs, and Pointers

    Hi, what I'm doing is reading in information from a binary file, and storing that information into an array of structs. Here is that bit of code. Record in this case is my base struct.
    Code:
    int read_file( int filesize , int &count , Record *&ptr , fstream &file )
    {
        int i = 0;
    
        file.seekg(0,ios::end);          // move to end of file
        filesize = file.tellg();         // get number of byte in file
        count = filesize / sizeof(Record);  // compute number of records
        file.seekg(0,ios::beg);          // move to beginning of file
    
        ptr = new Record[count];
    
        for( i = 0 ; i < count ; i++ )
        {
            file.read( (char *) &ptr[i] , sizeof(Record) );
        }
    
        return count;
    }
    Once the entire binary file is read in, I no longer use the file until I am going to write to it. So in the run of the program I do all my messing around with the information within the structs after they are stored in this array.

    This is probably a simple question, but how do I allocate more space for new structs in this array? During the run of the program, I will be adding and deleting records, and as my code stands I only have enough room for what I read in originally, correct?

    After manipulating the info, it is all written back into the file.

    Thanks for any help.

  2. #2
    Registered User Mortissus's Avatar
    Join Date
    Dec 2004
    Location
    Brazil, Porto Alegre
    Posts
    152
    I would use std::list:
    Code:
    int read_file( int filesize , int &count , list<Record>& ptr , fstream &file )
    {
        int i = 0;
    
        file.seekg(0,ios::end);          // move to end of file
        filesize = file.tellg();         // get number of byte in file
        count = filesize / sizeof(Record);  // compute number of records
        file.seekg(0,ios::beg);          // move to beginning of file
    
        ptr = new Record[count];
    
        for( i = 0 ; i < count ; i++ )
        {
            Record r;
            file.read( (char *) &r , sizeof(Record) );
            ptr.push_back(r);
        }
    
        return count;
    }

  3. #3
    Confused Magos's Avatar
    Join Date
    Sep 2001
    Location
    Sweden
    Posts
    3,145
    You could allocate manually but it'd be much easier to do it using an STL vector.
    Code:
    std::vector<Record> data;
    
    data.reserve(count) //Reserves (note: NOT adds) a certain amount of elements, to speed things up. You may leave this out.
    
    for(int i = 0 ; i < count ; i++)
    {
        data.push_back(Record());
        file.read(static_cast<char*>(&data[i]), sizeof(Record));
    }
    alternatively:
    Code:
    std::vector<Record> data;
    
    data.resize(count);
    
    for(int i = 0 ; i < count ; i++)
    {
        file.read(static_cast<char*>(&data[i]), sizeof(Record));
    }
    If you do a lot of inserts/removals you may want to use an std::list instead, though you won't get direct access to the elements like in a vector.
    MagosX.com

    Give a man a fish and you feed him for a day.
    Teach a man to fish and you feed him for a lifetime.

  4. #4
    Registered User
    Join Date
    Feb 2005
    Posts
    11
    Hm, thanks for the suggestions guys. I'm doing this program for a class, and we haven't covered link-lists or vectors yet, so "technically" we can't use them.

    Is there any other way to do it, perhaps with pointers or some other method?

  5. #5
    Confused Magos's Avatar
    Join Date
    Sep 2001
    Location
    Sweden
    Posts
    3,145
    Write your own vector class that handles allocation? Other than that I can only suggest creating a slightly too large array and hope that the additional elements won't overflow it...
    Code:
    const int size = 5;
    const int real_size = 20;
    
    Record* data = new Record[real_size];
    int current_size = size;
    
    for( i = 0 ; i < size ; i++ )
    {
       file.read((char*)&data[i] , sizeof(Record));
    }
    To add a new element:
    Code:
    if(current_size >= real_size) std::cout << "BUFFER OVERFLOW, HAHAHA!";
    
    data[current_size] = Whatever_to_add;
    current_size++;
    Last edited by Magos; 02-15-2005 at 02:35 PM.
    MagosX.com

    Give a man a fish and you feed him for a day.
    Teach a man to fish and you feed him for a lifetime.

  6. #6
    Registered User Mortissus's Avatar
    Join Date
    Dec 2004
    Location
    Brazil, Porto Alegre
    Posts
    152
    Hey, please try this, and let me know if work. I have never used realloc before, and I am too lazy to make a real program to test it. But this piece of code compiles with the correct headers iostream, fstream and stdlib.h. Any error, that anyone spot, please post...

    Hope that helps!

    Code:
    // This is a simple function that adds a new record, given the file name,
    // the buffer, maximum size of the buffer and current index. You can easily
    // change this function to add a Record, instead of a file. 
    // It returns true when add succesfully
    bool add_record(Record*& ptr, int& maximum_size, int& current_index, ifstream& file)
    {
        // If the new record will overflow the buffer
        if( current_index+1 > maximum_size )
        {
            // Temporary pointer
            void* t_ptr;
            // Realloc memory, adding 5 space for more records at once
            t_ptr = realloc(ptr, maximum_size*sizeof(Record) + 5*sizeof(Record));
    
            if(t_ptr != NULL)
            {
                // If ok, the ptr can receive the new memory    
                ptr = static_cast<Record*>(t_ptr);
                // The maximum_size must be updated
                maximum_size = maximum_size + 5;
            }
            else
            {
                cerr << "Canīt alloc enough memory, sorry =(" << endl;
                return false;
            }
        }
    
        // Remember that, as our realloc is BEFORE the read,
        // current index must be initialized at -1.
        current_index++;
    
        file.read( (char *) &ptr[current_index], sizeof(Record));
    
        return true;
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Structs, pointers and functions
    By osici in forum C Programming
    Replies: 2
    Last Post: 04-29-2009, 12:35 AM
  2. passing structs & pointers to structs as arguments
    By Markallen85 in forum C Programming
    Replies: 6
    Last Post: 03-16-2004, 07:14 PM
  3. pointers to pointers within structs
    By Lord_azrael99 in forum C Programming
    Replies: 2
    Last Post: 08-28-2003, 04:29 AM
  4. array of pointers to structs
    By stumon in forum C Programming
    Replies: 7
    Last Post: 03-24-2003, 07:13 AM
  5. structs like pointers?
    By mart_man00 in forum C Programming
    Replies: 5
    Last Post: 03-14-2003, 03:16 AM