Брей цццц не е съвсем за начинаещи кода

.
Нормално както казах малки пропуски в основата за да не бишнеш сградате хвани малко С първо да погледнеш.
Ето го решението
Хедъра който се казва classes.h
#ifndef MYCLASS__HH
#define MYCLASS__HH
//това проверява дали е включен вече веднъж хедъра
// не го забравай да слагаш подобно нещо в бъдеще
#include<iostream>
#include<cstring>
#include<typeinfo>
#include<new>
#include<strstream>
int test=0;
using namespace std;
template<class TMP> TMP *dyn_save(TMP *temp, int length=0);
//Classes_begin.................................................................
class library {
public:
virtual void f() {}
};
class book : public library {
public:
~book() { delete name; delete year; cout << "Destructing Book !!!" << endl; }
char *name;
int *year;
int enter_info();
};
class item {
public:
~item() { cout << "Destructing Node !" << endl; }
library *pData;
item *pNext;
};
class stack {
item *top;
public:
~stack() { cout << "Destructing Stack !" << endl; }
stack() { top = NULL; }
void push(library *obj);
item *pop();
};
class message {
public:
void enter_name(char *temp);
void enter_year(int *temp);
char *enter_book();
};
class error {
public:
char *memory_error();
};
//Classes_end...................................................................
bool yes_or_no(char *x);
#endif
//Край на хедъра
това ти е С файла не забравай разширението .cpp
Аз го кръстих mycode.cpp
#include "classes.h"
template<class TMP>
TMP *dyn_save(TMP *temp, int length=0) {
TMP *mem;
try {
if(length){
if(typeid(*temp) == typeid(char)) {
mem = new TMP[length+1];
if(temp!=NULL)
memcpy(mem, temp, length+1);
}
else {
mem = new TMP[length];
if(temp!=NULL)
memcpy(mem, temp, (sizeof(temp[0])*length));
}
} else {
mem = new TMP;
if(temp!=NULL)
*mem = *temp;
}
} catch(bad_alloc x) {
return NULL;
}
return mem;
}
//Class_Functions_begin.........................................................
int book::enter_info() {
char *temps=NULL;
int *tempi=NULL;
temps = dyn_save(temps, 1000);
if(temps==NULL) return -1;
tempi = dyn_save(tempi);
message msg;
msg.enter_name(temps);
this->name = dyn_save(temps, strlen(temps));
delete []temps;
msg.enter_year(tempi);
this->year = dyn_save(tempi);
delete tempi;
return 0;
}
void stack::push(library *obj) {
item *node=NULL;
node = dyn_save(node);
node->pData = obj;
node->pNext = top;
top = node;
}
item *stack::pop() {
book *pBook;
item *temp;
pBook = dynamic_cast<book *> (top->pData);
cout << "Name: " << pBook->name;
cout << endl;
cout << "Year: " << *(pBook->year);
cout << endl;
delete pBook;
temp = top;
top = top->pNext;
delete temp;
return top;
}
void message::enter_name(char *temp) {
bool correct;
char *c;
//........................................
if(test==1) {
cin.getline(temp,1000);
}
test = 1;
//........................................
do {
correct = true;
cout << "Enter a name: ";
cin.getline(temp,1000);
for(c=temp; *c!='\0'; c++)
if(!((*c>='a' && *c<='z') || (*c>='A' && *c<='Z') || *c=='\"' || *c=='.' || *c=='\\' || *c==' ')) {
correct = false;
break;
}
} while(correct==false);
}
void message::enter_year(int *temp) {
do {
cout << "Enter a year: ";
cin >> *temp;
} while(*temp<0 || *temp>2009);
}
char *message::enter_book() {
char buf[1000];
ostrstream msg(buf, sizeof(buf));
msg << "Would you like to enter a book ? ";
msg << '\0';
char *temp;
temp = dyn_save(buf, strlen(buf));
return temp;
}
char *error::memory_error() {
char buf[1000];
ostrstream err(buf, sizeof(buf));
err << "There isn't enough memory available!" << endl;
err << "Free more memory if you would like to continue ? y/n: ";
err << '\0';
char *temp;
temp = dyn_save(buf, strlen(buf));
return temp;
}
//Class_Functions_end...........................................................
//Main_Functions_begin..........................................................
int main() {
book *Book=NULL;
stack *stk=NULL;
stk = dyn_save(stk);
message *msg=NULL;
msg = dyn_save(msg);
error *err=NULL;
err = dyn_save(err);
int no_mem;
do {
begin: //This is used by goto.
Book = dyn_save(Book);
no_mem = Book->enter_info();
if(no_mem==-1) {
if(yes_or_no(err->memory_error())==false) break;
else goto begin;
}
stk->push(Book);
cout << flush;
} while(yes_or_no(msg->enter_book())==true);
cout << endl;
while(stk->pop()!=NULL)
cout << endl;
delete stk;
cout << "Sucess !";
return 0;
}
//Main_Functions_end............................................................
//Functions.....................................................................
bool yes_or_no(char *x) {
char y_n;
try {
cout << x;
delete x;
cin >> y_n;
throw y_n;
} catch(char y_n) {
if(y_n=='y') return true;
else return false;
}
}
Компилира се с командата
c++ -o mycode mycode.cpp
За cin.getline() го погледни на дебъгера :-) помни последния ентер от клавиатурата - не го обработваш. Това е причината да ти излиза. А за това че е тъпо да ползваш флаг и то глобален - спор няма. Но все пак по добре със флага работещо отколко чисто и неработещо.
Няколко забележки:
1. Дава при компилация съобщение за внимание - обърни му внимание и нанеси корекциите (опцията -Wno-deprecated е забранена да я използваш

)
2. Използването template<class TMP> не е препоръчително - прави кода по трудно четим. В дадени случаи ако работите повече разработчици времето за откриване на изключения ще е повече от спестеното.
3. try/catch се използват когато много те мързи да провериш изключенията. Вина се базира на многократно повторение на този код. Но по-добре така отколкото без проверка.
4. Елегантно решение if(temps==NULL) return -1;
5. Правилно
this->year = dyn_save(tempi);
delete tempi;
return 0;
}
Въпреки че живота на указателя tempi е между фигурните скоби (говоря за gcc g++ >2.х.х) по-добре е да се използва (може пък поредната версия да е бъгава кой-знае).
6. Не е коректна проверката има още условия освен това от 0 година едва ли ще вкарваш записи. Съобщението трябва да ти казва и формата на годината за глупави потребители като мене.
do {
cout << "Enter a year: ";
cin >> *temp;
} while(*temp<0 || *temp>2009);
7. Глупаво ограничение без проверка
char *message::enter_book() {
char buf[1000];
Какво става ако вкарам 1001 символа за книга - гърми
8. Същото като 7 ама тука си се презастраховал имаш константни съобщения
char *error::memory_error() {
char buf[1000];
ostrstream err(buf, sizeof(buf));
9. Красота
book *Book=NULL;
10. Забрави че съществува това в езика С и С++ - използвай структура от типа do{....}while();
Много грозно и не стилно е в структурен език да се ползва goto
goto begin;
11. Това да не е пример от С книжка за вин.

На такова ми бие. Хубавите книжки не ти препоръчват ОС или начин на компилиране. Нета също така не е книга - всекакви хора има там.
Не приемай много присърце коментара, но е добре да го разбереш, това все пак е моя стил.
Успех