Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

RFpro.ru: Программирование на C / C++


Хостинг портала RFpro.ru:
Московский хостер
Профессиональный ХОСТИНГ на базе Linux x64 и Windows x64

РАССЫЛКИ ПОРТАЛА RFPRO.RU

Лучшие эксперты по данной тематике

Асмик Гаряка
Статус: Академик
Рейтинг: 10523
∙ повысить рейтинг »
Коцюрбенко Алексей aka Жерар
Статус: Советник
Рейтинг: 4213
∙ повысить рейтинг »
CradleA
Статус: Бакалавр
Рейтинг: 2488
∙ повысить рейтинг »

/ КОМПЬЮТЕРЫ И СОФТ / Программирование / C/C++

Номер выпуска:1747
Дата выхода:24.05.2012, 15:30
Администратор рассылки:Киселёва Алёна aka Verena (Академик)
Подписчиков / экспертов:137 / 92
Вопросов / ответов:1 / 1

Консультация # 186114: Здравствуйте! У меня возникли сложности с таким вопросом: Написать программу для работы с перемешанной таблицей, использующей перемешивание сцеплением, по запросу оператора. Перемешанная таблица представлена массивом указателей на элементы таблицы, имеющие следующую структуру: struct Item{ int key; /* ключ элемента char *info; /*указ...


Консультация # 186114:

Здравствуйте! У меня возникли сложности с таким вопросом:
Написать программу для работы с перемешанной таблицей, использующей перемешивание сцеплением, по запросу оператора.
Перемешанная таблица представлена массивом указателей на элементы таблицы, имеющие следующую структуру:
struct Item{
int key; /* ключ элемента
char *info; /*указатель на информацию
Item *next; /* указатель на следующий элемент
};
Максимальный размер массива указателей ограничен (для задания максимального размера использовать константу - например, const int SIZE =...;).
Предусмотреть следующие операции:
-включение нового элемента в таблицу при условии, что в таблице не может быть двух элементов с одинаковыми ключами; если при включении нового элемента возникает такая ситуация, на экран должно быть выведено сообщение об ошибке;
- удаление элемента из таблицы по заданному ключу. Если запрошенный элемент в таблице отсутствует, вывести на экран сообщение об ошибке;
-по иск в таблице элементов по заданному диапазону ключей; результатом поиска должна новая таблица, содержащая найденные элементы;
-вывод содержимого таблицы на экран.

Разработать два варианта программ:
а)и сама таблица, и информация, относящаяся к элементу таблицы, хранятся в основной памяти;
б)и сама таблица, и информация, относящаяся к элементу таблицы, хранятся во внешней памяти ( используется двоичный файл произвольного доступа). Все операции выполняются с таблицей, размещенной в основной памяти. Таблица считывается из файла ( или создается в первый раз) в начале сеанса работы и записывается в файл в конце сеанса работы. Информация, относящаяся к элементу таблицы, записывается в файл сразу же при выполнении операции включения в таблицу. Имя файла вводится по запросу программы.

Примечания:
1. Программа должна содержать несколько функций; функция main должна выполнять: вывод меню, ввод и анализ ответа, вызов на исполнение требуемой функции;
2. В п рограмме нужно предусмотреть проверку правильности ввода данных;
3.Для варианта б) следует модифицировать структуру, определяющую элемент таблицы, включив в нее длину информации и ее смещение в файле;
4. В варианте б) для работы с файлом использовать функции пакета stdio.h; чтение запись выполнять с помощью fread() и fwrite(), в которых должна быть указана реальная длина информации.

Дата отправки: 20.05.2012, 17:05
Вопрос задал: ШмонинЕА (Посетитель)
Всего ответов: 1
Страница онлайн-консультации »


Консультирует Лысков Игорь Витальевич (Старший модератор):

Здравствуйте, ШмонинЕА!
Вот Вам программы. Старался комментировать подробно...
Но, если что непонятно, спрашивайте...
а)

Код :
#include <locale>
#include <iostream>

using namespace std;
                                                                                                                                                                                      
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;		//ключ элемента
	char	*info;		//указатель на информацию 
	Item	*next;		//указатель на след. элемент
}ITEM;

char *mesMain[] =		//сообщения меню
{
	"Включить новый элемент",
	"Удалить элемент",
	"Найти элемент из диапозона ключей",
	"Вывести таблицу",
	"Выход"
};
//количество пунктов меню
int MesMainCount = sizeof( mesMain ) / sizeof( mesMain[0] );
//функции отработки пунктов меню
void ( *funcMain[] )()={AddElement, 
						DelElement,
						SearchRange,
						OutTable,
						Exit};

ITEM	*table[SIZE];	//таблица-вектор

//Поиск элемента и места, куда вставить
//Вызывается при добавлении нового элемента
//параметры: ключ и адрес указателя в цепочке 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);
	pItem->info = new char[strlen(str)+1];
	strcpy(pItem->info, str);		//добавляем строку

									//определимся со ссылкой на наш элемент
	if (pItemPrev != NULL)			//если вставляется не в начало цепочки
		pItemPrev->next = pItem;	//то предыдущий будет на него ссылаться
	else
		table[num%SIZE] = pItem;	//если первый элемент, то запоминаем ссылку в массиве table
	cout << "Элемент добавлен" << endl;
}

//поиск элементов из интервала ключей
void SearchRange()
{
	int		i = -1;				//для поиска с начала таблицы
	ITEM	*pItem;
	int		count, min, max;

	cout << "Введите минимальный  ключ диапозона: ";
	min = GetNum();		//вводим ключ

	cout << "Введите максимальный ключ диапозона: ";
	max = GetNum();		//вводим ключ
	
	count = 0;			//посчитаем, чтобы определить нашли или нет

	while (FindRange(min, max, &i, &pItem))
	{							//выводим
		cout << "key = " << pItem->key				//ключ
			 << ", info = " << pItem->info			//строка
			 << endl;
		count++;									//считаем
	}
	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->info;		//удаляем строку
			delete pItem;				//и сам элемент
			cout << "Элемент удален" << endl;
			return;
		}
		pItemPrev=pItem;				//сдвигаем указатель на предыдущий элемент
	}
	//прошли всю цепочку, значит не нашли
	cout << "Элемент не найден" << endl;
}

//вывод всей таблицы
void OutTable()
{
	int		i, count = 0;	//посчитаем число элементов
	ITEM	*pItem;

	for(i=0; i<SIZE; i++)	//по всем элементам таблицы
	{
		//по всем элементам цепочек
		for (pItem = table[i]; pItem; pItem=pItem->next)
		{
			cout << "key = " << pItem->key 
				 << ", info = " << pItem->info
				 << endl;
			count++;
		}
	}
	if (0 == count)			//сообщение для пустой таблицы
		cout << "Таблица пуста" << endl;
}

//выход, удалим все элементы
void Exit()
{
	ITEM	*pItem, *pItemNext;
	for (int i=0; i<SIZE; i++)
	{
		for (pItem=table[i]; pItem; pItem=pItemNext)
		{
			pItemNext = pItem->next;		//запомним уазатель на следующего
			delete [] pItem->info;			//удаляем текущего
			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;
		cout << "Ваш выбор: ";
		//вводим число
		ret = GetNum();
	}
	//проверим на допустимость
	while ( ret < 1 || ret > max );
	//вернем номер строки
	return ret;
}

int main()
{
	int ret;
	system("chcp 1251 >> nul");
//    locale::global(locale("Russian_Russia.866")); //чтобы писалось по-русски
	do
	{
		ret = ViewMenu(mesMain, MesMainCount);	//выводим меню, вводим номер строки
		funcMain[ret-1]();						//отрабатываем пункт меню
		cout << "--------------------------------" << endl;
		if (ret == MesMainCount)				//последняя - выход
			break;
	}
	while ( ret );
	return 0;
}

б)
Код :
#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;
		cout << "Ваш выбор: ";
		//вводим число
		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;
}

Консультировал: Лысков Игорь Витальевич (Старший модератор)
Дата отправки: 21.05.2012, 00:06
Рейтинг ответа:

НЕ одобряю 0 одобряю!


Оценить выпуск | Задать вопрос экспертам

главная страница  |  стать участником  |  получить консультацию
техническая поддержка  |  восстановить логин/пароль

Дорогой читатель!
Команда портала RFPRO.RU благодарит Вас за то, что Вы пользуетесь нашими услугами. Вы только что прочли очередной выпуск рассылки. Мы старались. Пожалуйста, оцените его. Если совет помог Вам, если Вам понравился ответ, Вы можете поблагодарить автора - для этого в каждом ответе есть специальные ссылки. Вы можете оставить отзыв о работе портале. Нам очень важно знать Ваше мнение. Вы можете поближе познакомиться с жизнью портала, посетив наш форум, почитав журнал, который издают наши эксперты. Если у Вас есть желание помочь людям, поделиться своими знаниями, Вы можете зарегистрироваться экспертом. Заходите - у нас интересно!
МЫ РАБОТАЕМ ДЛЯ ВАС!



В избранное