Шаблон иерархической структуры данных в памяти (динамический массив указателей на записи)

Страницы работы

Фрагмент текста работы

другой соответственно меняются местами указатели на строки. Проще говоря меняется логический номер строки. Но при этом сам файл ни как не модифицируется для того что бы он соответствовал массиву указателем его надо обновить.

GetSz();

Метод возвращает количество строк в файле.

SaveInsert(cstring);

Вставка с сохранением порядка, сначала вставляем потом сортируем, что тут еще можно сказать?

LoadFromTXT(char*);

Загрузка из текстового файла.

SaveToTXT(char*);

Сохранение в текстовый файл.

Show();

Метод выводит данные из файла на консоль.


ПРИЛОЖЕНИЕ.

Текст программы:

course_3_5.cpp

/*Двоичный файл содержит записи переменной длины строки таблицы с заданной структурой столбцов. Формат записи предполагает ее

переменную размерность. Реализовать набор операций над записями без загрузки одновременно всей таблицы в память (поэлементная

загрузка СД) : добавление строки таблицы, извлечение, удаление, вставка по логическому номеру и редактирование (обновление)

строки, вставка с сохранением порядка, сортировка (возможно, через внешний текстовый файл), экспорт строк из текстового файла,

постраничный просмотр. При открытии файла производится его последовательный просмотр и составляется структура данных, содержащая

адреса (указатели) записей в файле. При изменении размерности записи она переписывается в конец файла. При завершении работы

программы записи переписываются в выходной двоичный файл в логическом порядке следования в структуре данных.

            Варианты структуры даннных :

                         Динамический массив указателей на записи.*/

# include <conio.h>

# include <stdio.h>

# include <string.h>

# include <fstream.h>

# include <stdlib.h>

class cstring{

char     *str;

            void     load(char *s) { str=strdup(s); }

            void     add(char *s)

                                   {

                                   char *q=new char[strlen(str)+strlen(s)+1];

                                   strcpy(q,str);

                                   strcat(q,s);

                                   str=q;

                                   }

            int       find(char *s){ char *q=strstr(str,s); return q==NULL ? NULL : q-str; }

public:

            cstring(){str=NULL;}

            cstring(char *_str){

            int size=strlen(_str);

            str=new char[size];

            strcpy(str,_str);

            }

            int       Get(char *s)               // Загрузка из текстовой строки (внешняя форма)

                        { this->~cstring(); load(s); return 1; }

            char     *Put()             // Сохранение в текстовой строке (динамический массив)

                        { return strdup(str); }

            void                Load(istream &I)                              // Загрузка из символьного потока

                        { char c[80]; I.getline(c,80); this->~cstring(); load(c);}    

            void     Save(ostream &O)                                        // Сохранение в символьный поток

                        { O << str; }  

            int                   BLoad(fstream &I)                            // Загрузка из двоичного потока

                        {

                        int sz;

                        this->~cstring();

                        int tst=I.tellg();

                        I.read((char*)&sz,sizeof(int));

                        if (!I.good()) { load("???"); return 0; }

                        str=new char[sz+1];

                        str[sz]=0;

                        I.read(str,sz);

                        return I.good();

                        }

            int                   BSave(fstream &O)                          // Сохранение в двоичного поток

                        {

                        int sz=strlen(str);

                        O.write((char*)&sz,sizeof(int));

                        O.write(str,sz);

                        return O.good();

                        }

            int                   Type(){ return 2;}                 // Возвращение идентификатора класса

            char     *Name(){ return "string"; }              // Возвращение имени класса

            int                  Cmp(cstring *q)                    // Сравнение объектов класса

                        {

                        if (Type()!=q->Type()) return Type()-q->Type();

                        return strcmp(str,((cstring*)q)->str);

                        }

            cstring            *Copy()                                  // Создание динамической копии объекта

                        { return new cstring(str); }

            int                   Add(cstring *q)                     // Сложение объектов

                        {

                        if (Type()!=q->Type()) return 0;

                        add(((cstring*)q)->str);

                        return 1;

                        }

            cstring& operator =(cstring &R){

            this->~cstring();

            this->load(R.Put());

            return *this;

            }

            cstring& operator =(char *R){

            this->load(R);

            return *this;

            }

            cstring& operator +=(char *R){

                        if(str==NULL) {str=new char [strlen(R)]; strcpy(str,R);

                                   str[strlen(R)]='\0';

                                   return *this; }

            add(R);

            return *this;

            }

            cstring& operator +=(cstring &R){

            this+R;

            return *this;

            }

            friend ostream &operator<<(ostream& IO, cstring &t)

                        { IO << t.str; return IO; }

            friend istream &operator>>(istream &IO, cstring &t)

                        { char c[80]; IO.getline(c,80); t.~cstring(); t.load(c); return IO; }

            cstring operator+(char *s)

                        { cstring x(str); x.add(s); return x; }

            cstring operator+(cstring &t)

                        { return *this + t.str; }

            friend cstring operator+(char *s, cstring &t)

                        { cstring x(s); x.add(t.str); return x; }

            int operator[](char *s) { return find(s); }

            operator int() { return strlen(str); }

            cstring operator()(int n1,int n2=-1){

                        if (n2==-1) n2=strlen(str);

                        if (n1>n2 || n2>strlen(str)) return cstring("???");

                        char c=str[n2];

                        cstring t(str+n1);

                        str[n2]=c;

                        return t;

                        }

            cstring operator-(char *s){}

            cstring operator-(cstring &t) { return *this-t.str; }

            int operator==(cstring &t) { return strcmp(str,t.str)==0; }

            int operator==(char *t)             { if(t==NULL && str!=NULL) return 0;

                                                                                               if(str==NULL && t!=NULL) return 0;

                                                                                               if(str==NULL && t==NULL) return 0;

                                                                                              return strcmp(str,t)==0; }

            int operator!=(cstring &t) { return strcmp(str,t.str)!=0; }

            int operator!=(char *t)              { if(t==NULL && str!=NULL) return 1;

                                                                                               if(str==NULL && t!=NULL) return 1;

                                                                                               if(str==NULL && t==NULL) return -1;

                                                                                               return strcmp(str,t)!=0; }

            int operator< (cstring &t) { return strcmp(str,t.str)< 0; }

            int operator<=(cstring &t) { return strcmp(str,t.str)<=0; }

            int operator> (cstring &t) { return strcmp(str,t.str)> 0; }

            int operator>=(cstring &t) { return strcmp(str,t.str)>=0; }

            int test(){if(str==NULL) return 0; return 1; }

};

class BinaryFile{

private:

            fstream file;

            cstring FileName;

            int *Adresa;

            int sz;

public:

            BinaryFile();

            ReallocAdresa(int*,int);

            BinaryFile(char*);

            CloseBinaryFile();

            Add(cstring);

            LoadAll(char*);

            SetSz(int);

            cstring GetByNumer(int);

            DeleteString(int);

            SaveAs(char*,char*);

            ReSave();

            InsertByNumer(int,cstring);

            Edite(int);

            void Sort(int, int);

            GetSz();

            SaveInsert(cstring);

            LoadFromTXT(char*);

            SaveToTXT(char*);

            Show();

};

BinaryFile::SaveToTXT(char *FName){     //Сохрание в текстовый файл                                                                                                       

            fstream TXT(FName,ios::out);         //Открывает текстовый файл для записи

            for(int i=0;i<GetSz();i++){   //Идем по структуре и сохраняем ее в текстовый файл

                        TXT<<GetByNumer(i+1)<<'\n';

            }

TXT<<"~end~"<<endl;                                                        //Отмечаем конец файла меткой ~end~

}

BinaryFile::Show(){                                                 //Метод выводит на экран двоичный файл

            cstring TMP;

            for(int i=0;i<GetSz();i++){               //Тоже, что и в пердыдущем методе, идем по файлу и выводим на экран все что в нем хранится

                        TMP=GetByNumer(i+1);

                        TMP.Save(cout);

                        cout<<endl;

                        if(i+1%11==0) {cout<<"Press any key"<<endl; getch(); }//Как только выведем десять cтрок остановить работу программы пока не будет нажата любая кнопка

            }

cout<<endl;

}

BinaryFile::LoadFromTXT(char *Fname){            //Загрузка из текстового файла

            int i=0;

            fstream TXT(Fname,ios::in);                                   //Открываем текстовый файл для чтения

            fstream Bin("TMP.tmp",ios::binary|ios::out);

            Bin.write((char*)&i,sizeof(int));//Резевируем место в двоичном файле под его размер

            cstring tmp;

            TXT>>tmp;//Четаем из текстового файла по строке и записываем ее в выходной двоичный пока не встретим строку ~end~

            while(tmp!="~end~"){

                        i++;                                        //Считаем количество строк в текстовом файле

                        tmp.BSave(Bin);

                        TXT>>tmp;

            }

            Bin.seekg(0,ios::beg);                                   //Записываем в начала двоичного файла количество хранящихся в нем строк

            Bin.write((char*)&i,sizeof(int));

            Bin.close();

            TXT.close();

            LoadAll("TMP.tmp");

}

BinaryFile::SaveInsert(cstring STR){          //Вставка с сохранением порядка, сначала вставляем потом сортируем

            InsertByNumer(1,STR);

            Sort(0,GetSz()-1);

}

int BinaryFile::GetSz(){return sz;}  //Метод возвращает количесво строк в двоичном файле

void BinaryFile::Sort(int a, int b){   //Быстрая сортировка массива указателей

int i,j,mode;

char *Left,*Right;

if (a>=b) return;                                  // Размер части =0

for (i=a, j=b, mode=1; i < j; mode > 0 ? j-- : i++){

    Left=GetByNumer(i+1).Put();

            Right=GetByNumer(j+1).Put();

            if (strcmp(Left, Right)==1){    // Перестановка концевой пары

     int c = Adresa[i]; Adresa[i] = Adresa[j]; Adresa[j]=c;

     mode = -mode;                                 // со сменой сокращаемого конца

}}

Sort(a,i-1); Sort(i+1,b);

}

BinaryFile::ReallocAdresa(int *NewArray, int NewSize){//Расширение, сужение массива указателей метод необходим когда мы вставляем или удаляем элемент массива Adresa

            delete Adresa;

            Adresa=new int[NewSize];

            for(int i=0;i<NewSize;i++){

                        Adresa[i]=NewArray[i];

            }

            sz=NewSize;

}

BinaryFile::Edite(int numer){                                  //Изменить строку

            cstring TMP("edited");

            DeleteString(numer);

            InsertByNumer(numer,TMP);

            ReSave();

}

BinaryFile::InsertByNumer(int numer, cstring STR){//Вставка по лог номеру

            fstream append("noname.cw",ios::binary|ios::in|ios::out|ios::ate);

            int pos=append.tellg();

            STR.BSave(append);                         //Записываем в конец файла новый элемент

            int *TMP=new int[sz+1];          //Создаем новый массив указателей на строки в файле

            int j=0;                                                   //потому как старый изменился

            for(int i=0;i<sz+1;i++)

            {if (i!=numer-1) {TMP[i]=Adresa[j]; j++;} else TMP[i]=pos; }  

            ReallocAdresa(TMP, ++sz);

            append.close();

}

BinaryFile::ReSave(){/*Перезапись файла, необходима если например изменился порядок следования элементов или просто добавили элемент, при вставке удалении

Похожие материалы

Информация о работе