Консультация № 186147
22.05.2012, 16:47
94.84 руб.
0 4 1
Здравствуйте! У меня возникли сложности с таким вопросом:
Надо исправить программу так, чтобы максимальное число символов в наименовании ключа было 8 символов,если больше то должен выдавать ошибку,и при выводе на экран строчки не залезали в чужие колонки.

Заранее спасибо!

Приложение:
#include <iostream>
#include <string>

//для файлов
#include <stdio.h>

using namespace std;

//максимальный размер
const int SIZE = 5;

//элемент таблицы
struct Item
{
int busy; //признак занятости элемента
int key; //ключ элемента (не может быть равен 0)
int par; //ключ родительского элемента
char* info; //указатель на информацию

//для файла
int len; //длина информации
int offset; //смещение в файле

};

//таблица
struct Table
{
Item items[SIZE];
int n; //количество элементов

string filename; //имя файла таблицы
FILE * pFile; //указатель на файл
};

istream& input(int& v)
{
while (!(cin >> v))
{
if (cin.eof())
break;
cin.clear();
cin.ignore();
}
return cin;
}

bool Find_dup_key(Table* t,int key)
{
for(int i=0;i<SIZE;i++)
{
if (t->items[i].busy && key == t->items[i].key)
return false;
}
return true;
}

bool Find_parent_key(Table* t,int pkey)
{
for(int i=0;i<SIZE;i++)
{
if (t->items[i].busy && pkey == t->items[i].key)
return true;
}
return false;

}

int Free_pos(Table* t)
{
for(int i=0;i<SIZE;i++)
{
if (!t->items[i].busy)
return i;
}
return -1;
}

void Add(Table* t)
{
cout << "\tВставка нового элемента в таблицу" << endl<<endl;

cout << "Ключ: ";
int key;
cin >> key;

cout << "Ключ родителя: ";
int pkey;
cin >> pkey;

if (key<1)
{
cout << "Ошибка: Ключ не может быть равным 0 или отрицательным" << endl;
return;
}
if (!Find_dup_key(t,key))
{
cout << "Ошибка: Дублирование ключей" << endl;
return;
}
if (pkey && !Find_parent_key(t,pkey))
{
cout << "Ошибка: Не найден родительский ключ" << endl;
return;
}

int pos = Free_pos(t);
if (pos<0)
{

pos = Free_pos(t);
if (pos<0)
{
cout << "Ошибка: Переполнение, таблица занята полностью" << endl;
return;
}
}

cout << "Информационное поле: " << endl;
cin.ignore();
string info;
getline(cin,info);

t->items[pos].busy = 1;
t->items[pos].key = key;
t->items[pos].par = pkey;
char* inf = new char[info.length()+1];
strcpy(inf,info.c_str());
t->items[pos].info = inf;

/* добавление в файл */

t->items[pos].len = strlen(t->items[pos].info);
t->items[pos].offset = ftell(t->pFile);
size_t result = fwrite(t->items[pos].info,1,t->items[pos].len,t->pFile);
if (result!=t->items[pos].len)
{
cout << "Ошибка: При добавлении в файл таблицы информации" << endl;
exit(1);
}

/* ----------------- */

t->n++;
cout << "Запись успешна добавлена"<<endl;

return;
}

void del_child(Table* t,int key)
{
for(int i=0;i<SIZE;i++)
{
if (t->items[i].busy && t->items[i].par == key)
{
t->items[i].busy = 0;
del_child(t,t->items[i].key);
t->n--;
}
}

}
void Del(Table *t)
{
cout << "\tУдаление элемента из таблицы" << endl<<endl;

cout << "Ключ: ";
int key;
cin >> key;

for (int i=0;i<SIZE;i++)
{
if (t->items[i].busy && key == t->items[i].key)
{
t->items[i].busy = 0;
del_child(t,key);
cout << "Запись успешно удалена" << endl;
t->n --;
return;
}
}
cout << "Ошибка: Ключ не найден"<< endl;

return;
}

//нужна для сжатия и освобождения памяти busy-нулевых элементов
void Reorganize(Table *t)
{
int i=0,j=SIZE-1;
while (true)
{
while(i<j && t->items[i].busy) //ищем пустой элемент
i++;
while(i<j && !t->items[j].busy) //ищем занятый
j--;
if (i<j) //меняем местами занятый и пустой элемент
{
if (t->items[i].info)
delete [] t->items[i].info; //освобождаем память у удалённого элемента
t->items[i] = t->items[j];
t->items[j].info = NULL;
t->items[j].busy = 0;

}
else
break;
}

//реорганизация файла
if (freopen(t->filename.c_str(),"wb",t->pFile) == NULL)
{
cout << "Ошибка: При реогранизации файла таблцы" << endl;
exit(1);
}

for(int i=0;i<t->n;i++)
{
//t->items[i].len = strlen(t->items[i].info);
t->items[i].offset = ftell(t->pFile);
size_t result = fwrite(t->items[i].info,1,t->items[i].len,t->pFile);
if (result!=t->items[i].len)
{
cout << "Ошибка: При добавлении в файл таблицы информации" << endl;
exit(1);
}

}

return;
}

void Output(Table *t)
{
if (!t->n)
{
cout << "Таблица пуста" << endl;
return;
}

cout << "Ключ\tРодит.ключ\tИнформ.поле" << endl;
for (int i=0;i<SIZE;i++)
{

if (t->items[i].busy)
{
cout.width(3);
cout << t->items[i].key;
cout.width(8);
cout << t->items[i].par;
//cout.width(5);
cout << "\t\t";
cout << t->items[i].info << endl;
}

}


return;
}



void Exit(Table* t)
{
return;
}

//удаление таблицы из памяти
void DeleteTable(Table* t)
{
for(int i=0;i<SIZE;++i)
{
if (t->items[i].info)
delete [] t->items[i].info;
}
delete t;

}

void FileName(Table* t)
{
/*
if (t->filename.length() > 0)
cout << "Текущее название файла: " << t->filename << endl;
cout << "Введите название файла" << endl;
*/
return;
}

int menu()
{
const char* msg[] = {"1. Ввод нового элемента","2. Удаление элемента","3. "Сборка мусора"","4. Вывод содержимого","5. Имя файла","0. Выход"};
int count = sizeof(msg)/sizeof(msg[0]);

cout << endl;
for(int i=0;i<count;i++)
cout << msg[i] << endl;

int ans;

const char* err = "";
do
{
cout << err << endl;
err = "Неправильное значение";
input(ans);
} while (ans<0 || ans>count);
return ans;
}

void init_table(Table* t)
{
t->n = 0;
for (int i=0;i<SIZE;i++)
{
t->items[i].busy = 0;
t->items[i].info = NULL;
t->items[i].key = 0;
t->items[i].par = 0;
}
}

//Работа с файлами

void loadTable(Table* t,string file)
{
t->pFile = fopen(file.c_str(),"rb");
t->filename = file;
if (t->pFile == NULL)
{
//если файла нет, то создаюм его
t->pFile = fopen(file.c_str(),"wb");
cout << "Создан пустой файл для таблицы: " << file;
}
else
{
//файл существует

//читаем метаданные
char buf[80];
strncpy(buf,file.c_str(),74); //80 - '_meta'
strcat(buf,"_meta");

FILE* pTemp = fopen(buf,"rb");
if (pTemp == NULL)
{
cout << "Не найден мета-файл для файл-таблицы " << file << endl;
abort();
}

//читаем метаданные
int n;
if (fread(&n,sizeof(int),1,pTemp)!=1)
{
cout << "Ошибка: При чтении количества элементов из файла метаданных" << endl;
abort();
}
t->n = n;

size_t result = fread(t->items,sizeof(Item),n,pTemp);
if (result != n)
{
cout << "Ошибка: При чтении элементов из файла метаданных" << endl;
abort();
}
fclose(pTemp);

//загружаем информацию
for (int i=0;i<n;i++)
{
fseek(t->pFile,t->items[i].offset,SEEK_SET);
t->items[i].info = new char[t->items[i].len+1];
result = fread(t->items[i].info,1,t->items[i].len,t->pFile);
t->items[i].info[t->items[i].len]=0;

if (result != t->items[i].len)
{
cout << "Ошибка: При чтении информации из файла" << endl;
abort();
}

}

//переоткрываем файл
freopen(t->filename.c_str(),"ab",t->pFile);
fseek(t->pFile,0,SEEK_END);
}
}

void saveTable(Table *t)
{
//сохранение таблицы (метаданных) в файл

char buf[80];
strncpy(buf,t->filename.c_str(),74); //80 - '_meta'
strcat(buf,"_meta");

FILE* pTemp = fopen(buf,"wb");
if (pTemp == NULL)
{
cout << "Ошибка: Не удалось создать файл метаданных" << endl;
exit(1);
}

//
size_t result = fwrite(&t->n,4,1,pTemp);
if (result != 1)
{
cout << "Ошибка: При записи в файл метаданных количества элементов таблицы" << endl;
exit(1);
}
//

for(int i=0;i<SIZE;i++)
{
if (t->items[i].busy)
{
result = fwrite(&t->items[i],sizeof(Item),1,pTemp);
if (result != 1)
{
cout << "Ошибка: При записи в файл метаданных элементf таблицы" << endl;
exit(1);
}

}
}

fclose(pTemp);
fclose(t->pFile);

}

int main()
{
setlocale(LC_ALL,"RUSSIAN"); //русская локаль

Table* table = new Table;

//считывание таблицы
string file;
cout << "Введите имя файла таблицы" << endl;
do
{
getline(cin,file);

} while (file.length() < 1);

init_table(table);
loadTable(table,file);


int answer = -1;
void (*pfun[])(Table*) = {Exit,Add,Del,Reorganize,Output,FileName};
while (answer)
{
answer = menu();
pfun[answer](table);
}

saveTable(table);
DeleteTable(table);
return 0;
}

Обсуждение

Неизвестный
22.05.2012, 17:04
общий
Надо исправить программу так, чтобы максимальное число символов в наименовании ключа было 8 символов,если больше то должен выдавать ошибку


Добавь проверку чтобы ключ не превышал число 99 999 999
давно
Профессор
230118
3054
23.05.2012, 00:14
общий
Что-то такое
if (key>99 999 999)
{
cout << "Ошибка: Ключ не может быть большим 99 999 999" << endl;
return;
}
начиная со строки 96
Неизвестный
24.05.2012, 17:16
общий
Адресаты:

Раз автор вопроса не отозвался, оформите кто-нибудь ответ.
Неизвестный
25.05.2012, 00:37
общий
25.05.2012, 00:43
это ответ
Здравствуйте, Никулин Михаил!

Необходимо в функцию Add добавить проверку, чтобы ключ не превышал числа 99999999. Т.е. функция должна выглядеть примерно так

Код:

void Add(Table* t)
{
cout << "\tВставка нового элемента в таблицу" << endl<<endl;

cout << "Ключ: ";
int key;
cin >> key;

cout << "Ключ родителя: ";
int pkey;
cin >> pkey;

if (key<1)
{
cout << "Ошибка: Ключ не может быть равным 0 или отрицательным" << endl;
return;
}
if (key>99999999)
{
cout << "Ошибка: Ключ не может быть больше 99 999 999" << endl;
return;
}

if (!Find_dup_key(t,key))
{
cout << "Ошибка: Дублирование ключей" << endl;
return;
}
if (pkey && !Find_parent_key(t,pkey))
{
cout << "Ошибка: Не найден родительский ключ" << endl;
return;
}

int pos = Free_pos(t);
if (pos<0)
{

pos = Free_pos(t);
if (pos<0)
{
cout << "Ошибка: Переполнение, таблица занята полностью" << endl;
return;
}
}

cout << "Информационное поле: " << endl;
cin.ignore();
string info;
getline(cin,info);

t->items[pos].busy = 1;
t->items[pos].key = key;
t->items[pos].par = pkey;
char* inf = new char[info.length()+1];
strcpy(inf,info.c_str());
t->items[pos].info = inf;

/* добавление в файл */

t->items[pos].len = strlen(t->items[pos].info);
t->items[pos].offset = ftell(t->pFile);
size_t result = fwrite(t->items[pos].info,1,t->items[pos].len,t->pFile);
if (result!=t->items[pos].len)
{
cout << "Ошибка: При добавлении в файл таблицы информации" << endl;
exit(1);
}

/* ----------------- */

t->n++;
cout << "Запись успешна добавлена"<<endl;

return;
}
Форма ответа