#include <locale>
#include <iostream>
using namespace std;
void ReadTableFromFile(void);
void WriteTableToFile(void);
void AddElement(void);
void DelElement(void);
void SearchRange(void);
void OutTable(void);
void Exit(void);
int GetNum(void);
const int SIZE = 10;
typedef struct Item
{
int key; //???? ????????
int seek; //???????? ???? info ???????????? ?????? ????? ? ?????
int len; //????? info
Item *next; //????????? ?? ????. ???????
}ITEM;
char *mesMain[] = //????????? ????
{
"???????? ????? ???????",
"??????? ???????",
"????? ???????? ?? ????????? ??????",
"??????? ???????",
"?????"
};
//?????????? ??????? ????
int MesMainCount = sizeof( mesMain ) / sizeof( mesMain[0] );
//??????? ????????? ??????? ????
void ( *funcMain[] )()={AddElement,
DelElement,
SearchRange,
OutTable,
Exit};
int StringsOff; //?????? ????? ? ?????
ITEM *table[SIZE]; //???????-??????
FILE *file = NULL; //????????? ?? ???????? ????
char fName[256];
//?????? ??????? ?? ?????
//?????? ?????:
//int StringsOff - ?????? ????? ? ?????
//ITEM *table[SIZE] - ??????? (???), ????? ??????? ???????? ??????? ?????????
//... - ?????? info
void ReadTableFromFile()
{
int i;
ITEM *pItem, *pItemPrev;
cout << "??????? ??? ?????: ";
cin.getline(fName, 256); //?????? ??? ?????
file = fopen(fName, "r+b"); //????????? ?? ??????/??????, ??? ????????
if (NULL == file) //???? ??? ??????
{
file = fopen(fName, "w+b"); //?? ??????? ????? ????
if (file) //?????????
{ //??????? ???? ? ?????? ????????
//???????? ????? ????? ????? ???? ???? ??????????
//? ?????? ???? ????????
StringsOff = sizeof(ITEM*) * SIZE + sizeof(int);
//????? ???????? ????? ????? ? ?????
fwrite(&StringsOff, sizeof(int), 1, file);
//??????? ?????? ??????????
fwrite(table, sizeof(ITEM*), SIZE, file);
}
else
cout << "?????? ???????? ?????" << endl
;
}
else //???? ????
{ //?????? ???????? ????? ????? ? ?????
fread(&StringsOff, sizeof(int), 1, file);
for (i=0; i<SIZE; i++) //?????? ???????? ???????
{ //?????? ????????? ? ???????
fread(&pItem, sizeof(ITEM*), 1, file);
if (pItem) //????????? - ?????? ????? ????????!
{
while(pItem) //?????? ??????? ?????????, ???? ????????? ?????????
{
pItem = new(ITEM); //??????? ???????
if (table[i] == NULL) //???????
table[i] = pItem; //?????????? ????????? ? ???????
else //???????? - ?????? ?????? ? ??????????? ?? ????????
pItemPrev->next = pItem;
//?????? ? ????? ???????
fread(pItem, sizeof(ITEM), 1, file);
pItemPrev = pItem; //?????????? ????????, ??? ?????? ???????????
pItem=pItem->next; //? ?????????? ? ??????? ????? ????? ????
}
}
else //??????? - ????????? ???!
table[i] = NULL;
}
}
fclose(file); //???? ?????????
}
//?????? ??????? ? ???? (? ????? ??????)
void WriteTableToFile()
{
ITEM *pItem;
int i, len;
fpos_t pos; //??????? ? ?????
void *pStrings; //????? ?????? ??? ?????? ??????? ?????
if (fName[0]) //???????? ?? ??????? ????? ?????
{
file = fopen(fName, "r+b"); //????????? ?? ??????/??????
if (file) //?????????
{
//????????? ?????? ????? ?? ?????
//????????? ????? ?????
fseek(file, 0, SEEK_END); //? ????? ?????
fgetpos(file, &pos); //?????????? ???????
fseek(file, StringsOff, SEEK_SET); //? ?????? ??????? ?????!
len = (int)pos - StringsOff; //????? ??????? ?????
pStrings = malloc(len); //??????? ?????? ??? ?????? ?????
fread(pStrings, len, 1, file); //?????????
fseek(file, 0, SEEK_SET); //??????? ? ?????? ?????!
//????????? ????!
fwrite(&StringsOff, sizeof(int), 1, file); //?????? ??????? ?????
//??????? ???????
for (i=0; i<SIZE; i++)
{
//????????? ?????? ??????? (??? 0)
fwrite(&table[i], sizeof(ITEM*), 1, file);
//??????? ????????? ???????
for (pItem=table[i]; pItem; pItem=pItem->next)
fwrite(pItem, sizeof(ITEM), 1, file);
}
//??????? ?????? ????? ? ????????? ????? ???????? ??????? ?????!
StringsOff = ftell(file); //????? ??????? ????? ?????? ???????
fwrite(pStrings, len, 1, file); //????? ??????????? ?????? ?????
fseek(file, 0, SEEK_SET); //? ?????? ?????!
fwrite(&StringsOff, sizeof(int), 1, file); //? ????? ????? ???????? ??????? ?????
fclose(file); //???? ?????????
free(pStrings); //??????????? ?????? ??? ??????
}
else
cout << "?????? ???????? ?????" << endl
;
}
else
cout << "??? ????? ?? ??????" << endl
;
}
//????? ???????? ? ?????, ???? ????????
//?????????? ??? ?????????? ?????? ????????
//?????????: ???? ? ????? ????????? ? ??????? next, ???? ??????? ????? ???????
//??? NULL, ???? ??????? ?????
//?????????? true, ???? ??????? ?????? ? false, ???? ?? ??????
bool Find(int num, ITEM **ppItem)
{
ITEM *pItem;
int i = num%SIZE; //??????? ??????????? - ??????? ?? ??????? ?? SIZE=10
//????????? - ??????????? ????
//??????, ???? ?? ??? ???????? ????
//*ppItem ? ????? ????? ????????? ?? ?????????? ????????? ???????,
//????? ???????? ?? ??????? ?????
for (*ppItem=NULL,pItem=table[i]; pItem!=NULL; pItem=pItem->next)
{
*ppItem = pItem; //?????????? ????????? ??????????? ??????????
//???? ??????? ????
if (pItem->key == num) //???? ?????!
return true; //???????
}
return false; //?? ?????, ? *ppItem ????? ????????? ?????????? (??? NULL)
}
//????? ?? ???? ??????? ????????? ? ?????? ? ???????? ????????? [min, max]
//??? ??????? ?????? ?????????? ?????? *idx = -1
//????? ??????? ?????? ?? ???? ??????? ????? ???????????? ?????? ? ??????? ? ?????
//???????????????? ??????? ????????.
//????????? ????? ????? ????????? ? ???? ?? ?????.
//?.?., ????? ????? ??? ???????? ? ?????
bool FindRange(int min, int max, int *idx, ITEM **ppItem)
{
ITEM *pItem;
int i;
if (min > max) //?? ?????? ??????, ???????? min < max
{
i = min;
min = max;
max = i;
}
if (*idx == -1) //?????? ??????
{
i = 0; //???????? ? 0-?? ???????
pItem=table[0];
}
else //??????????? ??????
{
i = *idx; //??????
pItem = (*ppItem)->next; //????????? ?? ????????????!
}
while (i<SIZE) //?? ???? ???????
{
for(; pItem; pItem=pItem->next) //?? ????????? ????? ???????
{
//????????? ??????? ????????? ????? ? ????????
if ((pItem->key >= min) && (pItem->key <= max))
{ //?????
*idx = i; //????????? ??????
*ppItem = pItem; //? ????????? ?? ???????
return true; //?????!
}
}
pItem=table[++i]; //?? ?????? ??????? ????????? ???????
//??? ????????? ????? ?????????????? ?????
//?? ?? ?????? ?? while(i<SIZE) !
}
return false; //?????? ???
}
//?????????? ???????? ? ???????
void AddElement()
{
int num; //?????? ?????? ????????
char str[80];
ITEM *pItem; //????????? ?? ??????? ???????
ITEM *pItemPrev; //????????? ?? ???????, ????? ???????? ???????
cout << "??????? ???? ????????: ";
num = GetNum(); //?????? ????
if(Find(num, &pItemPrev))
{
cout << "??????? ? ????? ?????? ??? ????" << endl
;
return;
}
pItem = new ITEM; //??????? ????? ???????
//????????? ????
pItem->key = num; //????
pItem->next = NULL; //??????? ?????????? ???????? ? ???????
cout << "??????? ??????: ";
cin.ignore();
cin.getline(str, 80);
if (fName[0]) //???????? ?? ??????? ????? ?????
{
file = fopen(fName, "r+b"); //?????????
if (file) //?????????
{
//????????? ???????? ?????? ? ??????? ?????
fseek(file, 0, SEEK_END); //?????????? ? ????? ?????
pItem->seek = ftell(file)-StringsOff; //?????????? ???????, ???
// ???????? ? ??????? ????? ???? info
pItem->len = strlen(str)+1; //?????????? ????? ??????
fwrite(str, pItem->len, 1, file); //? ????? ?????? ? ????? ?????
fclose(file); //????????? ????
//??????????? ?? ??????? ?? ??? ???????
if (pItemPrev != NULL) //???? ??????????? ?? ? ?????? ???????
pItemPrev->next = pItem; //?? ?????????? ????? ?? ???? ?????????
else
table[num%SIZE] = pItem; //???? ?????? ???????, ?? ?????????? ?????? ? ??????? table
cout << "??????? ????????" << endl
;
}
else
cout << "?????? ???????? ?????" << endl
;
}
else
cout << "??? ????? ?? ??????" << endl
;
}
//????? ???????? ???? ??????
//????? ????????? ?? ????????? ??????
void SearchRange()
{
int i = -1; //??? ?????? ? ?????? ???????
ITEM *pItem;
int count, min, max;
char str[80];
cout << "??????? ??????????? ???? ?????????: ";
min = GetNum(); //?????? ????
cout << "??????? ???????????? ???? ?????????: ";
max = GetNum(); //?????? ????
count = 0; //?????????, ????? ?????????? ????? ??? ???
if (fName[0]) //??? ????? ???????
{
file = fopen(fName, "r+b"); //????????? ????
if (file) //?????????
{
while (FindRange(min, max, &i, &pItem))
{
fseek(file, pItem->seek+StringsOff, SEEK_SET); //?????????? ? ???????, ??? ?????????? ??????
fread(str, pItem->len, 1, file); //?????? ?????? ????? ????
//???????
cout << "key = " << pItem
->key
//????
<< ", info = " << str //??????
<< endl;
count++; //???????
}
fclose(file); //???? ?????????
}
else
cout << "?????? ???????? ?????" << endl
;
}
else
cout << "??? ????? ?? ??????" << endl
;
if (0==count) //??????? ?????????, ???? ?? ?????
cout << "???????? ?? ???????" << endl
;
}
//???????? ???????? ? ???????? ??????
//???? ?? ????????????.
//???????? ?????????? ?????? ? ??????!
void DelElement()
{
int i, num;
ITEM *pItemPrev, *pItem, *pItemNext;
cout << "??????? ???? ????????: ";
num = GetNum(); //?????? ????
i = num%SIZE; //??????? ??????????? - ??????? ?? ??????? ?? SIZE=10
//????????? - ??????????? ????
//?? ???? ????????? ??????? ??? ???????????? ?????
for (pItemPrev=NULL,pItem=table[i]; pItem; pItem=pItemNext)
{
pItemNext = pItem->next; //????????? ?? ??????????
//?????????? ????
if (pItem->key == num)
{ //??????? ??????? ?? ??????? ??????????
if (pItemPrev == NULL) //?????? ??????? ? ????????
table[i] = pItemNext; //????? ? ?????? table ????? ??????????
else //?????, ?????????? ?????????
pItemPrev->next = pItemNext; //?? ??????????
delete pItem; //??????? ???????
cout << "??????? ??????" << endl
;
return;
}
pItemPrev=pItem; //???????? ????????? ?? ?????????? ???????
}
//?????? ??? ???????, ?????? ?? ?????
cout << "??????? ?? ??????" << endl
;
}
//????? ???? ???????
void OutTable()
{
int i, count = 0; //????????? ????? ?????????
ITEM *pItem;
char str[80];
if (fName[0]) //??? ????? ???????
{
file = fopen(fName, "r+b"); //????????? ????
if (file) //?????????
{
for(i=0; i<SIZE; i++) //?? ???? ????????? ???????
{
//?? ???? ????????? ???????
for (pItem = table[i]; pItem; pItem=pItem->next)
{
fseek(file, pItem->seek+StringsOff, SEEK_SET); //?????????? ? ???????, ??? ?????????? ??????
fread(str, pItem->len, 1, file); //?????? ?????? ????? ????
cout << "key = " << pItem
->key
<< ", info = " << str
<< endl;
count++;
}
}
fclose(file); //???? ?????????
}
else
cout << "?????? ???????? ?????" << endl
;
}
else
cout << "??? ????? ?? ??????" << endl
;
if (0 == count) //????????? ??? ?????? ???????
cout << "??????? ?????" << endl
;
}
//?????, ?????? ??? ????????
void Exit()
{
ITEM *pItem, *pItemNext;
WriteTableToFile(); //???????? ??????? ? ?????
//?????? ???????? ??????? ?? ????? ?????????
for (int i=0; i<SIZE; i++)
{
for (pItem=table[i]; pItem; pItem=pItemNext)
{
pItemNext = pItem->next; //???????? ???????? ?? ??????????
delete pItem;
}
}
}
//???? ?????
int GetNum()
{
int a;
cin >> a;
while ( !( cin.good() || cin.eof() ) || ( a < 0 ) )
{
cout << "??????? ?????! " << endl
;
cin.clear();
cin.ignore();
cin >> a;
}
return a;
}
//????? ???? ? ?????? ?????? ??????
int ViewMenu(char** mes, int max)
{
int ret;
do
{
//????
for ( int i = 0; i < max; i++ )
cout << i
+1 << ". " << mes
[i
] << endl
;
//?????? ?????
ret = GetNum();
}
//???????? ?? ????????????
while ( ret < 1 || ret > max );
//?????? ????? ??????
return ret;
}
int main()
{
int ret;
system("chcp 1251 >> nul");
// locale::global(locale("Russian_Russia.866")); //????? ???????? ??-??????
ReadTableFromFile(); //?????? ??????? ?? ????? (??? ??????? ?????)
do
{
ret = ViewMenu(mesMain, MesMainCount); //??????? ????, ?????? ????? ??????
funcMain[ret-1](); //???????????? ????? ????
cout << "--------------------------------" << endl
;
if (ret == MesMainCount) //????????? - ?????
break;
}
while ( ret );
return 0;
}