Thread: First time implementing direct file access. What's the best way to do this?

  1. #1
    Registered User
    Join Date
    Jan 2007
    Posts
    14

    First time implementing direct file access. What's the best way to do this?

    This is the code I currently have. As you can see, its got a long way to go. What I need to do is be able to save and load the private data in the Book and Patron objects in such a way that I can access any given record without reading the whole thing. Strings have to be converted to old style C strings so that the Book and Patron records are all of fixed length so they can be saved in direct access files.

    My current approach is bad (copying to char arrays w/o null characters (haven't figured that one out yet), filling unused cells with special characters, use sentinel characters to delimit the names and numbers, then, when loading, read different parts of the stream into different variables and so on. I don't like it at all. I know that there is a (much) better way. I missed that class though. So, I could use some guidance. What's the best way to do this?

    Thanks for your time.

    Code:
    void Library::saveBooks(string save)
    {
    	ofstream osavefile ( "Books.sav" );
    	for(int i = 1; i<bidnumber; i++)
    	{
    		char title[80];
    		char author[80];
    		char subject[80];
    		unsigned long loanedto = 1000000000;
    		// Added to borrower ID to make it a fixed length
    		// number in the file. substracted after reading.
    		if (LOB[i].getTitle() != "rumuration")
    		// rumuration is returned if a book ID is unused.(book deleted previously)
    		{
    			// strcpy is no good. Whole point of converting is making each
    			// data structure take the same size on file for direct access.
    			strcpy(author, (LOB[i].getAuthor()).c_str());
    			strcpy(subject, (LOB[i].getSubject()).c_str());
    			strcpy(title, (LOB[i].getTitle()).c_str());
    			loanedto = 1000000000 + LOB[i].getBorrower();
    		}
    		osavefile<<title<<author<<subject<<loanedto;
    		// even if BookID is unused, some padding should
    		// be written to file for random access to work, right?		
    	}
    	osavefile.close();
    }
    Code:
    void Library::load()
    {
    	// Sacrifice goat and pray for miracle.
    }
    This is what Book and Patron objects look like (Patron inherits from Person which is also included).

    Code:
    #ifndef BOOK_H
    #define BOOK_H
    #include <string>
    #include "Patron.h"
    class Book
    {
    public:
    	Book();
    	//Removed bunch of accessor and mutator functions
    
    private:
    	string title;
    	string author;
    	string subject;
    	unsigned long idNumber; //unique number for this book
    	unsigned long checkedOutByPatronID ; //will be NULL if the book is available
    };
    Code:
    #ifndef PATRON_H
    #define PATRON_H
    #include "Person.h"
    #include <iostream>
    #define MAX_BOOKS 20
    
    	class ListOfBooks;
    	class Book;
    class Patron : public Person
    {
    	public:
    
    	Patron();
    	//Bunch of functions
    		
    private:
    
    	unsigned long idNumber;           //unique number for this patron
    	unsigned long hasCheckedOutBookID[MAX_BOOKS];
    	unsigned short numberOfBooksCheckedOut;
    };
    
    #endif
    Code:
    #ifndef PERSON_H
    #define PERSON_H
    #include <string>
    
    class Person
    {
    	public:
    	Person();
    	void editName(string s);
    	string getName();
    private:
    	string name;
    	int email;
    };
    
    #endif
    Last edited by Salem; 04-02-2007 at 10:40 AM. Reason: folding lines

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    You need to create some kind of struct to read and write direct to the file.
    Code:
    struct fileRec {
    		char title[80];
    		char author[80];
    		char subject[80];
    		unsigned long loanedto;
    };
    Then you say something like
    Code:
    		fileRec rec = { { 0 }, { 0 }, { 0 },  1000000000 };
    		// Added to borrower ID to make it a fixed length
    		// number in the file. substracted after reading.
    		if (LOB[i].getTitle() != "rumuration")
    		// rumuration is returned if a book ID is unused.(book deleted previously)
    		{
    			// strcpy is no good. Whole point of converting is making each
    			// data structure take the same size on file for direct access.
    			strcpy(rec.author, (LOB[i].getAuthor()).c_str());
    			strcpy(rec.subject, (LOB[i].getSubject()).c_str());
    			strcpy(rec.title, (LOB[i].getTitle()).c_str());
    			rec.loanedto = 1000000000 + LOB[i].getBorrower();
    		}
    		osavefile.write( &rec, sizeof rec );
    Make sure you opened the file in binary mode.

    For reading, you just use the .read() method with the same parameters.

    You can then seek to any record in the file by using sizeof(rec) * recordNumber as the offset into the file.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Jan 2007
    Posts
    14
    Thanks. After a long hesitation, I ended up saving the objects directly without going through an intermediate struct. the drawback was that I had to modify the datatypes of several private variables (from strings to char[]) and adapt my existing code accordingly (mostly accessor and mutator functions).

    It mostly works now, though some weird bug popped out that crashes the program when trying to print the patron's list after a load. It involves too much code for me to post it here though.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. opening empty file causes access violation
    By trevordunstan in forum C Programming
    Replies: 10
    Last Post: 10-21-2008, 11:19 PM
  2. Formatting a text file...
    By dagorsul in forum C Programming
    Replies: 12
    Last Post: 05-02-2008, 03:53 AM
  3. Formatting the contents of a text file
    By dagorsul in forum C++ Programming
    Replies: 2
    Last Post: 04-29-2008, 12:36 PM
  4. archive format
    By Nor in forum A Brief History of Cprogramming.com
    Replies: 0
    Last Post: 08-05-2003, 07:01 PM
  5. Need a suggestion on a school project..
    By Screwz Luse in forum C Programming
    Replies: 5
    Last Post: 11-27-2001, 02:58 AM