Помогите, пожалуйста оптимизировать код программы

  • Автор темы lrad
  • Дата начала
Статус
Закрыто для дальнейших ответов.
L

lrad

Условие задачи:
1. Описать класс (структуру) со следующими полями:
- фамилия, инициалы авторов;
- название книги;
- издательство;
- год издания;
- количество страниц;
- количество глав в книге;
- название дисциплины.
2. Написать программу, выполняющую следующие действия:
- ввод информации в файл;
- вывод всей информации на экран;
- вывод на экран информации о фамилии автора, название и количества страниц книги, обеспечивающих дисциплину, название которой введено с клавиатуры.
Код:
#include <iostream.h>
#include <fstream.h>
#include <string.h>
#include <conio.h>
#include <iomanip.h>
#include <stdlib.h>
#define FIO 20
#define name 20
#define PUBLISHERS 20
#define YEAR 4
#define PAGES 6
#define CHAPTER 6

//--------------------------------------------------------------------------------------
struct book
{
char fio[25];
char name_book [25];
char publishers[25];
int year_publishers;
int pages;
int chapter;
char discipline[17];
};
//----------------------------------------------------------------------------------------

// прототипы функций
void sozdanie();
void prosmotr();
void vibor();
void tabl(); 
//-----------------------------------------------------------------------------------------

// Опеpация-функция ввода с клавиатуpы
istream &operator >> (istream &in, book &x)
{
cout<<"\nФамилия и инициалы:";
in.seekg(0,ios::end);
in.get(x.fio,FIO-1,'\n');
cout<<" \nНазвание книги:";
in.seekg(0,ios::end);
in.get(x.name_book,name-1,'\n');
cout<<"\nИздательство:";
in.seekg(0,ios::end);
in.get(x.publishers,PUBLISHERS-1,'\n');
cout<<"\nГод издания:";
in.seekg(0,ios::end);
in >>x.year_publishers,YEAR-1;
cout<<"\nКоличество страниц:";
in.seekg(0,ios::end);
in >>x.pages, PAGES-1;
cout<<"\nКоличество глав в книге:";
in.seekg(0,ios::end);
in>>x.chapter, CHAPTER-1;
cout<<" \nНазвание дисциплины:";
in.seekg(0,ios::end);
in >>x.discipline;
return in;
}
//------------------------------------------------------------------------

// Опеpация-функция вывода на дисплей
ostream &operator << (ostream &out, book x)
{
out.setf (ios::left); // установка флага равнения по левому краю
out << "|" << setw(17) << x.fio << "|" << setw(15) << x.name_book 
<< "|"<< setw(11)<< x.publishers  << "|" << x.year_publishers
<< "|" << setw(4)<< x.pages << "|"<< setw(4)<< x.chapter 
<< "|" <<setw(16)<< x.discipline << "|\n";
return out;
}

// Опеpация-функция чтения из файла
ifstream &operator >> (ifstream &in, book &x)
{
in.getline(x.fio,FIO,'\n');
in.getline(x.name_book, name,'\n');
in.getline(x.publishers,PUBLISHERS,'\n');
in>>x.year_publishers,YEAR;
in>>x.pages, PAGES-1;
in>>x.chapter, CHAPTER-1;
in >>x.discipline;
in.seekg (2L, ios::cur);
return in;
}
// Опеpация-функция записи в файл
ofstream &operator << (ofstream &out, book &x)
{
out << x.fio << endl
<< x.name_book << endl
<< x.publishers << endl
<< x.year_publishers << endl
<< x.pages << endl
<< x.chapter << endl
<< x.discipline << endl;
return out;
}


//------------------------------------------------------------------------

void main(void)
{
char c;
while (1)
{
cout << endl << "1. Создание файла";
cout << endl << "2. Просмотр содержимого";
cout << endl << "3. Вывод на экран информации о фамилии автора," << endl;
cout <<"  название книги и количество страниц";
cout << endl << "4. Выход";
cout << endl << "Ваш выбор -> ";
cin.seekg(0,ios::end);
c = cin.get();
switch(c)
{																										  
case '1':
sozdanie();
break;

case '2':
prosmotr();
break;

case '3':
vibor();
break;

case '4':
return;




default:
cout << "Вводите только цифры от 1 до 4" << endl;
}
}
}


// определение функции вывода на экран шапки таблицы
void tabl()
{
cout << "-------------------------------------------------------------------------------------------\n";
cout << "|	 Ф.И.О.	 | Название книги|  Изд-во | Год|Стр.|Глав|	Дисциплина |\n";
cout << "|-----------------|--------------------|----- ------|-----|-----|------|-------------------|\n";
}



// определение функции создания файла
void sozdanie()
{
char c;
ofstream ff; // создание потока ff для записи в файл
book s;
ff.open( "bok.txt" );
// открытие файла book.txt и связывание его
// c потоком ff
if ( !ff) // проверка открытия файла
{
cerr << "Ошибка открытия файла bok.txt для записи\n";
exit(1);	 // аварийный выход
}

// Цикл записи элементов в файл
do
{
cin >> s;	// обращение к операции-функции ввода с клавиатуpы
ff << s;	// обращение к операции-функции записи в файл
cout<<"\nПpодолжить ввод?(Y/N или Д/H)";
cin.seekg(0L, ios::end);
c = cin.get();
}
while ( c == 'y' || c == 'Y' || c == 'д' || c == 'Д');
ff.close();	  // закpытие файла
}


// определение функции вывода всей информации на экран
void prosmotr()
{
ifstream finp; // создание потока finp для чтения из файла
book s;
finp.open( "bok.txt", ios::in );
// открытие файла bok.txt и связывание его
// с потоком finp

if ( !finp ) // проверка открытия файла
{
cerr << "Ошибка открытия файла bok.txt для чтения\n";
exit(1);	 // аварийный выход
}
cout << "\nСписок элементов из файла\n";
tabl(); // вывод на экран шапки таблицы
while ( finp )
{
finp >> s;  // обращение к операции-функции чтения из файла
if ( strlen ( s.discipline) <= 0 )
// длина первого поля в записи меньше либо равна нулю
break;	 // выход из цикла

cout << s;	// обращение к операции-функции вывода на экран
}
finp.close();	 // закpытие файла

}

// определение функции вывода на экран информации,
// отвечеющей условию поиска
void vibor()
{
char discipline[15]; // для ввода условия поиска
ifstream fi;	// создание потока fi для чтения из файла
book b;
fi.open("bok.txt", ios::in);
// открытие файла bok.txt и связывание его
// с потоком fi

if ( !fi ) // проверка открытия файла
{
cerr << "Ошибка открытия файла bok.txt для чтения\n";
exit(1);	 // аварийный выход
}

cout << "Введите название дисциплины:";
cin.seekg(0,ios::end);
cin.get(discipline,'\n');
cout << "Информация о книге\n";
tabl(); // вывод на экран шапки таблицы 
while (!fi.eof())
{
fi >> b;	  // обращение к операции-функции чтения из файла
if (strcmp(b.discipline,discipline)==0)
// дисциплины совпали 
cout << b;  // обращение к операции-функции вывода на экран
}
fi.close();

}
 
N

North

Что здесь оптимизировать ?
1. Чтение из файла ? Для этого можешь отмапить свой файл "bok.txt" с помощью функции MapViewOfFile( map_file, FILE_MAP_READ, 0, offset, len); таким образом содержимое файла последовательно записывается в память (подробности в MSDN)

2. Сравнение строк ? Функцию strcmp(b.discipline,discipline)==0 можно заменить, на сравнение кодов сравниваемых строк. Эти самые коды вычисляются заранее и представляют числовое значение соответствующее первым 6 символам в строке. Исли эти коды различны - строки уже различны, если коды одинаковы необходима проверка оставшихся n-6 символов строк. Это непросто и требует создания велосипеда вроде std::string.

3. Поиск ? Рекомендую использовать hash-функции, в первую очередь контейнер std::map
 
T

tansa

Ты не описал в чем проблемма.
Но я тебе могу сказать вот что(только косметика).

1.В C++ не модно писать #include <iostream.h>, вроде как нужно #include <iostream>. Может у тебя и компилится, но у меня LInux + gcc не хотят.
2. Вот за такое:
Код:
// прототипы функций
void sozdanie();
void prosmotr();
void vibor();
void tabl();

У меня в универе половину пунктов снимают сразу.

3. Определись с языком в котором пишешь, потому что если это C++, то в нем не приветствуются глобальные функции, а все это прячется в структуру. А если C, то там ты не перегрузишь операторов "<<", ">>" и т.п.

4. Чтобы работали cout, cin, и др. Тебе надо using namespace std; или писать "std::cout", но вообще изменение стандартного namespace'а не приветствуется.

5. А в чем собственно твой вопрос?
 
N

North

НА самом деле вся эта задача решается "десятью строчками" если использовать STL контейнеры и алгоритмы
 
L

lrad

1)Насчет #include <iostream> и using namespace std
у меня задание написать эту программу в среде борланд 3.11, а там без ".h" не компилируется и using namespace std выдает тут же ошибку
2)
НА самом деле вся эта задача решается "десятью строчками" если использовать STL контейнеры и алгоритмы
А как это сделать? Подскажите, пожалуйста
Дело в том, что я учусь на заочном за 300 км от универа и мне узнать больше негде
 
T

tansa

<!--QuoteBegin-lrad+1:05:2007, 12:02 -->
<span class="vbquote">(lrad @ 1:05:2007, 12:02 )</span><!--QuoteEBegin-->Дело в том, что я учусь на заочном за 300 км от универа и мне узнать больше негде
[snapback]64084" rel="nofollow" target="_blank[/snapback]​
[/quote]

Это уже зажисит от того, какое у тебя задание и как называется предмет. Потому что мне на объектовом программировании запрещали STL использовать.

А операторы << и >> лучше в структуру засунь.
 
L

lrad

Задание звучит так:
Задание: Задача по обработке файлов.
В этой контрольной работе студент должен самостоятельно определить структуру записи и характеристики ее элементов, выполнить описание данной структуры и написать программу, содержащую функции создания файла, вывода на экран всей информации и информации, соответствующей условиям поиска : напечатать фамилии авторов, названия и количество страниц книг, обеспечивающих дисциплину, название которой введено с клавиатуры.
Запись должна содержать следующую информацию: фамилия и инициалы авторов, название книги, издательство, год издания, количество страниц, количество глав в книге, название дисциплины.
Для проверки правильности работы программы ее нужно протестировать. Для этого необходимо записать в файл 8-10 записей и далее выполнить вывод на экран вначале всей инфомации, а затем информации, соответствующей условию поиска.

Предмет-Программирование на языках высокого уровня
 
N

North

Создаеш контейнер асоциированных пар для своих данных, т.е. [структура учебника:название предмета]

struct compare
{
bool operator()(const char* discip1, const char* discip2) const
{
return strcmp(discip1,discip2)==0;
}
};

std::map<const char*, struct book, compare> container;

первый параметр Key - в твоем случае это название предмета
второй Data - то что будет асоциировано с конкретным ключем (Key)
третий параметр compare - объект выполняющий сравнение ключей(дисциплин)

Заполняешь container. Далее испjльзуешь один из стандартных алгоритмов обьявленных в <alghoritm>, вроде std::find

Короче твоя задача сводится к заполнению структуры данных container и выводу на экран её содержимого.

ЕЩЕ. Среда разработки (Борданд С++ 3.11) ОЧЕНЬ устаревшая. Во время ее создания многого из вышеописанного могли еще не придумать :)

Рекомендую прислушаться к словам tansa, причесать код под C++, минимизировать операции чтения данных из файла (читай загружать содержимое файла в память и уже в памяти выполнять поиск и проч.)
 
L

lrad

а как засунуть операторы << и >> в структуру?
 
N

North

именно
istream &operator >> (istream &in, book &x);
ifstream &operator >> (ifstream &in, book &x);
ostream &operator << (ostream &out, book x);
ofstream &operator << (ofstream &out, book &x);

никак, у тебя это не получится
а вот:
void sozdanie();
void prosmotr();
void vibor();
void tabl();
следует вставить в структуру (сделать членами book)
 
T

tansa

<!--QuoteBegin-North+1:05:2007, 12:51 -->
<span class="vbquote">(North @ 1:05:2007, 12:51 )</span><!--QuoteEBegin-->никак, у тебя это не получится
[snapback]64095" rel="nofollow" target="_blank[/snapback]​
[/quote]
почему же не получится?

в структуре пишешь
Код:
ostream &operator << (ostream &out, const book& x);
ну а снаружи пишешь
Код:
book::ostream &operator << (ostream &out, const book& x)
{
out.setf (ios::left); // установка флага равнения по левому краю
out << "|" << setw(17) << x.fio << "|" << setw(15) << x.name_book 
<< "|"<< setw(11)<< x.publishers  << "|" << x.year_publishers
<< "|" << setw(4)<< x.pages << "|"<< setw(4)<< x.chapter 
<< "|" <<setw(16)<< x.discipline << "|\n";
return out;
}

И все впорядке....
 
N

North

Я не проверял твой код на работоспособность, но в своем суждении исхоу из следующего:

1. << бинарный оператор.
2. для любого бинарного оператора выражение a@b интерпретируется либо как a.operator @:)), либо как
operator @(a,:)

2.1 в первом случае ( a.operator @(B) ) функция operator@ определена как нестатический член (исключая new, delete и их вариации) класса A (а имеет тип A)
2.2 во втором случае ( operator @(a,B) ) есть функция-не-член классов (A и B)

3. Мы не можем изменять определение классов из std::. В том числе и std::eek:stream.

Есть тонкая разница:
Мы МОЖЕМ определить только
ostream &operator << (ostream &out);
как член класса book
при этом вызов данного оператора будет таким:
my_book << std::eek:ut;
хотя наиболее привычным является
std::eek:ut << my_book;


[ушел читать Книгу Создателя]
 
M

minsk_girl

Для: North
помоги, пожалуйста. Зайди на мою тему "помогите плиз девушке"
 
Статус
Закрыто для дальнейших ответов.
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!