Thread: Deleting/Searching Directly File I/O

  1. #1
    Registered User
    Join Date
    Feb 2003
    Posts
    23

    Deleting/Searching Directly File I/O

    Can someone post some code (preferably commented) of how to directly delete and search for a record in a flat text database, without completely reqwiting the database just deleting a single entry. Thank you.

  2. #2
    Used Registerer jdinger's Avatar
    Join Date
    Feb 2002
    Posts
    1,065
    That is extremely funny. I mean that is down right bold. Not only do you want someone to do your work but you want them to comment it for you.

    What have you tried? Do you already have your link list in place for creating the database and just need some help deleting a node and traversing the list in a search? How far have you gotten and what errors are you getting?

  3. #3
    Registered User
    Join Date
    Feb 2003
    Posts
    23
    Lol, i didnt mean it that way. I do though have a linked list thats fully functioning and the deleting, adding, and all other functions work with it. TMy problem though is that a requirement is to delte directly and search diretly from a fil, which I have noe idea how to do without loading the information into an array or linked list, then reqriting to a file. Any links or code will be of great help. Thank you.

  4. #4
    Used Registerer jdinger's Avatar
    Join Date
    Feb 2002
    Posts
    1,065
    Ok. Sorry if I mistook you, but the way your post was written came across like it was screaming of a homework assignment being pawned off on someone.

    Not knowing exactly what your text file looks like or what the data elements of your list's nodes it's hard to give an exact answer but here's possibility:

    Code:
    //if your node looks something like this:
    typedef _node
    {
       char Name[10];
       int Age;
       char State[3];
       _node *next;
       _node *prev
    } node, *pnode;
    
    
    //and your text file lists data one element per line, ie:
    //Bob
    //25
    //MO
    //Fred
    //34
    //NY
    //etc, etc.
    
    #include <fstream>
    using namespace std;
    
    //FIRST LOAD THE LIST INTO MEMORY FROM THE FILE
    
    void ReadTextFileIntoLinkedList(const char *FileName)
    {
       ifstream ifs;
       int i=0, age;
       node nd;
       char cName[11], cAge[3], cState[3];
       ifs.open(FileName);
       while(!ifs.eof())
       {
             //get 3 lines (which equal one node of data)
            ifs.getline(cName,10,'\n');
            ifs.getline(cAge,2,'\n');
            ifs.getline(cState,2,'\n');
            
            strcpy(nd.Name,cName);
            nd.Age = atoi(cAge);
            strcpy(nd.State,cState);
            
            AddANode(nd);
       }
       ifs.close();
    }
    
    //NEXT TRAVERSE THROUGH YOUR LIST UNTIL YOU FIND THE 
    //NODE WHO'S DATA MATCHES THE ONE YOU WANT TO DELETE
    //BEAR IN MIND THAT A LINEAR SEARCH WITH A STANDARD LINKED
    //LIST ON A LARGE DATABASE CAN BE TIME CONSUMING
    //AFTER YOU'VE FOUND AND DELETED THE NODE, CYCLE THROUGH
    //THE LIST FROM START TO END WRITING THE RESPECTIVE DATA
    //BACK INTO THE FILE USING AND ofstream (completely 
    //overwriting the original file).
    There are a many ways you coud do this (like I said not knowing what your text file looks like makes it difficult). This was just to give you an idea.

  5. #5
    Registered User
    Join Date
    Aug 2002
    Location
    Hermosa Beach, CA
    Posts
    446
    You had mentioned not overwriting the whole file. You can do this if you use a binary format for your file, and each record is a fixed length. Then you could use seekp(), seekg(), read(), write(), etc. to write the class object out to a particular offset into the file. For instance, if your record length was 200 bytes, and you wanted to write to record 15, you would use seekp to set the file pointer to 200 * 14, and then you would use write() to put the record to the file. Your data on disk would look like this:

    YourDataTypeKey key;
    YourDataType data;

    At startup, you could do one traversal to put all the offsets & keys into an in memory cache, and now you have constant time or near constant time lookup to find the exact record offset you need, and you only overwrite a single record on disk, with a single write.

    As it turns out, this is a bit of work. So you could also just do what was suggested, ie overwrite the whole file. In that case, I gave a posting on how to do that, a few postings down, I think the title has something to do with ios:ut or something.
    The crows maintain that a single crow could destroy the heavens. Doubtless this is so. But it proves nothing against the heavens, for the heavens signify simply: the impossibility of crows.

  6. #6
    Registered User
    Join Date
    Feb 2003
    Posts
    23
    Thanks IfYouSaySo you just solved my problem, thanks tot he binary I/O suggestion I can fullfill the requirement of direct access. Thanks again.

  7. #7
    Registered User
    Join Date
    Feb 2003
    Posts
    23
    Actually one more question. I know I can overwrite data ina binary file but say if I wanted to delete a binary 0 or 1 completely how could i do it.

  8. #8
    Registered User
    Join Date
    Aug 2002
    Location
    Hermosa Beach, CA
    Posts
    446
    I'm not sure if I understand what you are asking. But here is what I think. Lets say you have 10 records in a file. And each record is 200 bytes. And now you need to delete record 4, which means you use seekp to get to offset 200 * 3. Then you write out a record with write that is all zeros, ie.
    MyRec rec;

    // zero it, assuming the constructor doesnt do it already
    memset(&rec,0,sizeof(MyRec));

    // assume fs is your filestream, seek from beginning to 200*3
    fs.seekp(200*3, ios::beg);

    // write the null record
    fs.write(&rec,sizeof(MyRec));

    Now this record is "deleted", but when you go to add a new record to the file, you can append past the last record, ie seek to end of file and write the new record. The problem is that this leaves fragmentation in the file, which can't be recovered unless you do some kind of compaction from time to time. The other approach is to keep a "free list", a list of offsets which are deleted in the file. Now your add routine will check the free list to see if there is a location in the middle of the file somewhere to add, and if so, it removes the entry from the free list and uses it as the offset to add at, and if not it will append as before.

    You can do the free list in one of two ways. One way is to simply maintain the free list in memory, and when you first read in the file, you look at each record to see if it is all zeros, and if so, add to the free list. Ie. you are rebuilding the free list every time your app runs. The other approach is to keep a separate file, or a header block in the same file, that has free list info. For instance, as a separate file, it could just be a list of ints (offsets that are free). The problem with the header block is that you will run into complications if the size of your free list grows to be larger than whatever space you have allocated for the header block.

    Personally, I would just do the in-memory free list thing, much easier. Then again, I'm not even sure if this is what you were asking....but hopefully I cleared something up.
    The crows maintain that a single crow could destroy the heavens. Doubtless this is so. But it proves nothing against the heavens, for the heavens signify simply: the impossibility of crows.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Data Structure Eror
    By prominababy in forum C Programming
    Replies: 3
    Last Post: 01-06-2009, 09:35 AM
  2. File I/O Assertion Failure in VS2008
    By clegs in forum C Programming
    Replies: 5
    Last Post: 12-25-2008, 04:47 AM
  3. C++ std routines
    By siavoshkc in forum C++ Programming
    Replies: 33
    Last Post: 07-28-2006, 12:13 AM
  4. Game Pointer Trouble?
    By Drahcir in forum C Programming
    Replies: 8
    Last Post: 02-04-2006, 02:53 AM
  5. Unknown Memory Leak in Init() Function
    By CodeHacker in forum Windows Programming
    Replies: 3
    Last Post: 07-09-2004, 09:54 AM