Thread: file input output problem..

  1. #1
    Registered User
    Join Date
    Nov 2006
    Posts
    86

    file input output problem..

    hello guys, i know m rather new, so ill also give a quick introduction:

    my name is Sven Vranken, i live in belgium and im aged 16. in my free time i like to go out with frends, work out at the jym and i also like to go skateboarding some times.
    i first started programming cpp one year ago, im learning it at home.

    well m not so good in intro's so thats it for me.

    to be honest i came to this forum cause im totaly desperate. i cant seem to figure out my fault in my program. ill first tell you whats it all about.

    im making a program (almost complete) that makes a random acces data file, and i write 2 classes to it which share inheritance. after you write specific information to the file you can read it out later. but theirs something wrong, i searched alot and i figured out the problem is hiding in the part where the actual data file is build, the code is a bit to big to paste here (about 250 lines) so im going to paste the part where i think the problem is and m going to include the whole project in a .rar file for those who want to look further in it.


    thanx to annyone who replies

    Code:
    switch (choise)
       {
         case 1:    //chosen to create the file
         {
           cout <<" Create or renew the data file\n"<< endl;
    
            ofstream basic ("clients.dat",ios::binary);           // create a stream to output clients to //file ( im going to write 50 empty clients of each class to the file )
    
            if (!basic)
    
            {
              cout <<"File cannot be opened"<<endl;
              exit(1);
            }
    
            baseclass baseclient;  // create a basic client default constructor fills in data which 
           // is going to be written to the file 
    
    
            for (int x = 1; x<= 51; x++)
            {
              baseclient.setID(x);
    
    
              basic.write (reinterpret_cast < const char * > (&baseclient),
              sizeof (baseclass)); // write it binary 
    
            }
            basic.close();
            /*
             * im going to close the stream and create a new one to write the second class to it
             * altough this is not necissary, its better to understand;
             */
            cout <<"50 empty basic accounts created"<<endl;
            ofstream advanced ("clients.dat", ios::binary | ios::app);
    
            dirclass advancedclient; // create advancedclient (inherits from baseclient)
    
    
            for (int x = 52; x <= 102; x++)
            {
    
    
              advancedclient.setID(x);
    
              advanced.write(reinterpret_cast < const char* > (&advancedclient),
              sizeof (dirclass));
    
              cout << x << endl;
    
    
            }
            cout <<" 50empty advanced accounts created" << endl;
            cout <<"file (re)created with succes!"<<endl;

    and when i read the file out this is some of the output:

    Code:
    50                                 
    
    3      0 
    
                                             //baseclient id 50, 51 and so on (output right)
                                             // the spaces also are a part of the output 
    
    
    
    51                                 
    
    3      0 
    
                                            
    
    
    -----------READ FIRST 50 BASIC ACCOUNTS------------ // this worked out well.
    
    
    
    52                                 
    
    3      0   0       
    
                                            
    
                                                                                                        /* FIRST ADVANCED CLIENT
    outputs right!(all the id numbers (53,54.. also print out right  but all the actual data behind that dont print out right */
    
    
    53   `ø            ø             
    
    0      0   0       
    
    ‘|À$                                   
    
                                                                                                        
    
    54   `ø            ø             
    
    0      0   0       
    
    ‘|À$
    if u want to look in the whole source:
    (i could not upload all the files so here is the smallest part of it (the functions that are used in main ( i seperated them cause its easyer to read)
    :
    Mainfunctions.cpp :

    Code:
    #include <iostream>
    #include <iomanip>
    #include <fstream>
    #include "header2.h"
    #include <sstream>
    using namespace std;
    
    
    void printmainoptions ()
    {
      cout <<"1. To Create or renew the data file"   << endl;
      cout <<"2. To add or modify a new user"        << endl;
      cout <<"3. To view all the users"              << endl;
      cout <<"4. To exit"                            << endl;
    
      cout <<"\n"<<endl;
    
    }
    void writeinfo ()
    {
      cout <<"You can add a Basic user or an Advanced user\n"
           <<"To add a Basic user: "
           <<"please input an accountnumber from 1 to 51\n"
           <<"To add an Advanced user: "
           <<"please input an accountnumber from 51 to 101\n"
           << endl;
    }
    
    
    int getchoise ()
    {
      int choise;
      string kak;
    
    
    
      getline (cin,kak);
      stringstream(kak) >> choise;
      while (choise < 1 || choise > 103)
      {
        cout <<"Please input a valid number: ";
        getline (cin,kak);
        stringstream(kak) >> choise;
      }
      return (choise);
    }
    
    
    void outputline (ostream &output,baseclass &lol )
    {
      output <<left<<setw(5)<<lol.getID()
             <<setw(15)<<lol.getfname()
             <<setw(15)<<lol.getlname()
             <<"\n"<<setw(7)<<lol.getsex()
             <<setw(2)<<lol.getage()<<"\n"
             <<setw(40)<<lol.getwoonplaats()<<"\n"<<endl;
    }
    void Outputline (ostream &output,dirclass &loll)
    {
      output <<left<<setw(5)<<loll.getID()
             <<setw(15)<<loll.getfname()
             <<setw(15)<<loll.getlname()
             <<"\n"<<setw(7)<<loll.getsex()
             <<left<<setw(4)<<loll.getage()
             <<setw(8)<<loll.getsalary()<<"\n"
             <<left<<setw(40)<<loll.getwoonplaats()<<"\n"
             <<left<<setw(100)<<loll.raboutyourself()<<endl;
    
    
    }

    i realy hope u guys can help me

  2. #2
    Registered User
    Join Date
    Nov 2006
    Posts
    86
    no-1ne? please?

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Create a really simple test program which just perfoms one essential element of your program.
    Say for example writing two records to a binary file, then reading them back in again.

    Real simple like, two classes (one base, one derived), with one member variable and one access function each.
    Then the whole thing is one simple file of no more than 50 lines or so, which is likely to be read by more people (they can try it as well).

    Who know, you may figure out what the problem actually is with your code from studying the really simple case.
    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.

  4. #4
    Registered User
    Join Date
    Nov 2006
    Posts
    86
    ill try that , ty for the tip

  5. #5
    Registered User
    Join Date
    Nov 2006
    Posts
    86
    okay guys... ive solved it myself after lots of work. thanx annyway... for those who want to know what ive changed :

    Code:
    case 3:
         {
           cout <<"View all the registered clients:"<<endl;
           baseclass basicclient;
           dirclass  advancedclient;
    
    
    
           ifstream file ("clients.dat",ios::in | ios::binary );
    
           file.read (reinterpret_cast < char * > (&basicclient),
           sizeof (baseclass));
           while (basicclient.getID () <= 51)
           {
             outputline (cout,basicclient);
    
    
             file.read (reinterpret_cast < char * > (&basicclient),
             sizeof (baseclass));
           }
           cout <<"\n\n-----------READ FIRST 50 BASIC ACCOUNTS------------\n\n";
           file.close();
           ifstream File ("clients.dat",ios::in | ios::binary );
           advancedclient.setID(52);
           File.seekg ( (advancedclient.getID()-1)*sizeof (baseclass));
           /*
            *first was:
            *File.seekg ( (advancedclient.getID())*sizeof (dirclass));
            *
            */
    
    
           for  (int x = advancedclient.getID(); x<=102; ++x)
           {
    
             advancedclient.setID(x);
    
    
             Outputline (cout,advancedclient);
    
    
    
    
             File.read (reinterpret_cast <char *> (&advancedclient),
             sizeof (dirclass));
    
    
    
    
    
           }
    ill be sticking arround... atleast if you guys want me 2

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > File.seekg ( (advancedclient.getID()-1)*sizeof (baseclass));
    If you use the size of the object rather than the size of it's type, there's less chance of such mis-match problems.
    File.seekg ( (advancedclient.getID()-1)*sizeof (advancedclient));

    If the type of the object changes for some reason, then this part of the code will adapt automatically.
    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.

  7. #7
    Registered User
    Join Date
    Nov 2006
    Posts
    86
    i hit up on another problem... located in the section where the inputted data is written to the file its actually the same problem as the one with the outputting but i still cant get it right.

    the error is located in this part:
    Code:
    writeinfo.seekp ( (advancedclient.getID()-1) *
              sizeof (dirclass));
    
              writeinfo.write (reinterpret_cast < const char * > ( &advancedclient),
              sizeof (dirclass));
    im commanding the file pointer to go to the location of (advancedclient.getID()-1) jumping with sizes of "dirclass", but ofcourse this just cant work cause the first 50 classes saved in my file are of size "baseclass", now i tried the folowing:

    Code:
              baseclass basicclient;
              basicclient.setID(51);
    
              writeinfo.seekp ( (basicclient.getID()) *
              sizeof ( baseclass)) ;
    
              writeinfo.seekp ( (advancedclient.getID()-1) *
              sizeof (dirclass));
    i thought that, i could jump to the middle of the file with sizes of "baseclass" bytes, and then, when the pointer is at the last byte of the last baseclass record i start jumping with sizes of dirclass. but its not realy working... anny advice?

    (btw u can delete my very first post (cause its a long one and kinda annoying,and the attached files also arent up to date annymore, :P )
    Last edited by epidemic; 12-02-2006 at 05:34 PM.

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Use two separate files, one for each class?

    Always write a dirclass, even if you're only using the base class part of it, so you can change your mind later on and be sure that there will be room for whichever version you want.

    Though to be honest, I didn't think you could just read and write the binary data of things which are not PODs
    http://www.parashift.com/c++-faq-lit....html#faq-26.7
    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.

  9. #9
    Registered User
    Join Date
    Nov 2006
    Posts
    86
    Quote Originally Posted by Salem
    Use two separate files, one for each class?

    Always write a dirclass, even if you're only using the base class part of it, so you can change your mind later on and be sure that there will be room for whichever version you want.

    Though to be honest, I didn't think you could just read and write the binary data of things which are not PODs
    http://www.parashift.com/c++-faq-lit....html#faq-26.7

    yes , but i tought it would be a chalange to write them to the same file...
    kinda sucks to know i spend so much time to try and figure out a way to do somthing that actually is , not possible?. ill check your link out, thanx for the help.

    but i was wondering, those data files included with games, wich are like 150mb, cant all be of the same type can they? would supprise me if they did.

  10. #10
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Well in good programs, each class would have a mechanism to serialise it's data in such a way that individual members which are PODs will be written out individually, and read back in again in a predictable manner.

    It just takes a bit more work than simply pointing to the start of the class and writing sizeof() bytes. Which by the way breaks down horribly if your classes start to contain pointers, or say STL data structures.
    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.

  11. #11
    Registered User
    Join Date
    Nov 2006
    Posts
    86
    Ok, l leave it with writing them to a seperate file then , ty

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM
  2. Outputting to a File Modified Text
    By alpha in forum C++ Programming
    Replies: 8
    Last Post: 11-24-2003, 08:39 PM
  3. Confusing problem with file input
    By Vorok in forum C++ Programming
    Replies: 3
    Last Post: 01-05-2003, 03:49 AM
  4. problem with output
    By Garfield in forum C Programming
    Replies: 2
    Last Post: 11-18-2001, 08:34 PM
  5. Simple File Creation Algorithm
    By muffin in forum C Programming
    Replies: 13
    Last Post: 08-24-2001, 03:28 PM