другой соответственно меняются местами указатели на строки. Проще говоря меняется логический номер строки. Но при этом сам файл ни как не модифицируется для того что бы он соответствовал массиву указателем его надо обновить.
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(){/*Перезапись файла, необходима если например изменился порядок следования элементов или просто добавили элемент, при вставке удалении
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.