4pg.doc

download 4pg.doc

of 4

Transcript of 4pg.doc

  • 7/30/2019 4pg.doc

    1/4

    Program 4

    Write a C++ program to read and write student objects with variable-length records using

    any suitable record structure and to read from this file a student record using RRN.

    #include#include#include#include#include#include#include

    fstream file, index;class student{private: char name[100],usn[20];

    int m1,m2,m3;

    public: void getstuff();void pack();void marksdiv(char*,int);void lookup();void realunpack(char*);

    };

    void student :: marksdiv(char *digits,int m1){

    int r1,r2,q1,q2;r1=m1%100;q1=m1/100;digits[0]=q1+'0';

    r2=r1%10;q2=r1/10;digits[1]=q2+'0';digits[2]=r2+'0';

    }

    void student :: getstuff(){

    coutname;coutusn;coutm1>>m2>>m3;

    }

    void student:: pack(){

    int i,j;char buffer[500],digits[3];getstuff();i=0;while(name[i]!='\0')

  • 7/30/2019 4pg.doc

    2/4

    {buffer[i]=name[i];i++;

    }buffer[i++]='|';j=0;while(usn[j]!='\0'){

    buffer[i]=usn[j];i++;j++;

    }buffer[i++]='|';marksdiv(digits,m1);buffer[i++]=digits[0];buffer[i++]=digits[1];buffer[i++]=digits[2];buffer[i++]='|';marksdiv(digits,m2);buffer[i++]=digits[0];buffer[i++]=digits[1];

    buffer[i++]=digits[2];buffer[i++]='|';marksdiv(digits,m3);buffer[i++]=digits[0];buffer[i++]=digits[1];buffer[i++]=digits[2];buffer[i]='\n';for(j=0;j

  • 7/30/2019 4pg.doc

    3/4

    file.getline(buffer,MAXINT,'\n');if (file.fail()){ cout

  • 7/30/2019 4pg.doc

    4/4

    Therefore, the private data members of the student class will not change. But as usual, the

    public member functions will change a little bit.

    If we were to implement RRN on fixed-length records, then we would alwaysknow the length of all records as it is a constant. So, if we want to jump directly to the 5 th

    record in a file (RRN=5), we would do seekg((4 the length of a record) + 1)

    from the beginning of the file and access the required record directly. The addition of 1 atthe end is to jump past the inter-record separator\n.

    But with variable-length records, we cannot estimate the length of each record

    exactly. Therefore, we have to store the length of each record someplace. Now, if wewant to jump directly to the 5 th record in the file, we have to add the lengths of each of

    the first 4 records along with their inter-record separators, then add 1 to this sum, and

    then use seekg() to jump to this position in the file. In this implementation, we are

    storing the length of each variable-length record of a data file into another file.

    We open 2 files in main(), one called sumne.txt for storing variable-length

    records, and the other called sumne.idx to store the length of each of these records. Now,

    we open the sumne.idx in write mode and binary mode, since we wish to store the length

    of each record as an integer, and not as a sequence of characters like we stored the marksof each student after characterizing it using marksdiv().

    getstuff() and marksdiv() have the same functionality as before. pack() not

    only gets information for each student from the user using getstuff(), packs it into a

    buffer and writes this buffer to sumne.txt, but also writes the length (as an integer) of

    each record into sumne.idx. After packing information into the file, the control comes

    back to main() and the files are closed.

    The files are opened again in read mode, and now lookup() is called. We get the

    RRN from the user. If the RRN is 1, then we do not have to jump anywhere in the file

    because the file get pointer is already pointing at the right record. So we do not have to

    compute any byte offset.

    If RRN is greater than 1, say RRN=5, we get the first 4 entries from sumne.idxfile and accumulate their sum in the variable byte_offset. This variable now has the

    cumulative length of the first 4 records. Each time we add the value 2 to this sum. This isbecause, whenever DOS sees a \n character in a file, it replaces this by 2 characters \r

    and \n, which are the carriage return and the line feed characters. Hence, there are 2

    inter-record separators now one beside the other (and in all the earlier programs where \n

    is the inter-record separator). When jumping past records, we have to now jump past

    length of each record + 2. Each time we get a record from the file, we increment a

    counterrec_count so that we can stop at RRN-1.

    If it so happens that the EOF ofsumne.idx occurs before RRN-1 record is gotten

    to, then it means that too big a RRN has been entered. For eg., this happens if there are

    only 10 records in our file and we want the 15 th RRN record. It is enough to checkwhether there is no more data in sumne.idx instead of in sumne.txt, as sumne.idx has

    an integer corresponding to each record in sumne.txt.

    After computing the appropriate byte offset, we jump to that record using

    seekg(), then get that record using getline(). We then send it to realunpack(), which

    has the same functionality as in earlier programs, to display the contents of the record.