Verem betöltése és elmentése

Írjunk szöveges és bináris betöltést/elmentést az alábbi verem osztály számára!

class Stack

{

      unsigned int elementNum;

      int *pData;

 

public:

      Stack() {elementNum=0;pData=NULL;}

      // A másoló konstruktor szükséges a dinamikus adattagok miatt

      Stack(const Stack& theOther);

      // A destruktor felszabadítja a dinamikus adattagot

      ~Stack() {if(pData!=NULL) delete[]pData;}

     

      bool isEmpty()const{return !elementNum;}

      void pop(int& element);

      void push(int element);

      // Az = operátor, amely a mély másolást valósítja meg

      const Stack& Stack::operator = (const Stack& theOther);

};


A példa igényli az állomány végéig való olvasást, és a tömbök bináris kiírását. A konzolon/terminálon az állomány vége jel Windows alatt <Enter>Ctrl+Z<Enter>, Linux/Unix alatt Ctrl+D<Enter>.


A megoldásért kattints ide!

A Stack.h állomány:

#ifndef STACK_H

#define STACK_H

 

#include<stdio.h>

#include<stdexcept>

#include<string>

 

class stack_exception: public std::exception

{

      std::string message;

 

public:

      stack_exception(std::string message):message(message){};

 

      const char * what()const

      {

            return message.c_str();

      }

 

};

 

 

 

class Stack

{

      unsigned int elementNum;

      int *pData;

 

public:

      Stack() {elementNum=0;pData=NULL;}

      // A másoló konstruktor szükséges a dinamikus adattagok miatt

      Stack(const Stack& theOther);

      // A destruktor felszabadítja a dinamikus adattagot

      ~Stack() {if(pData!=NULL) delete[]pData;}

     

      bool isEmpty()const{return !elementNum;}

      void pop(int& element);

      void push(int element);

      // Az = operátor, amely a mély másolást valósítja meg

      const Stack& Stack::operator = (const Stack& theOther);

 

      void readBinary(std::istream& is);

      void writeBinary(std::ostream& os)const;

      void readText(std::istream& is);

      void writeText(std::ostream& os)const;

};

#endif /*STACK_H */

A Stack.cpp állomány:

#include <limits>

#include <assert.h>

#include "Stack.h"

#include <iostream>

#include <string>

 

using namespace std;

 

 

Stack::Stack(const Stack& theOther)

{

      // Az operator=-t hívjuk,

      // és az érvényes adatot feltételez

      pData = NULL;

 

      *this=theOther;

}

 

const Stack& Stack::operator = (const Stack& theOther)

{

      assert(this != &theOther);

 

      // Felszabadítjuk az eddigi adatokat

      if(pData!=NULL)

      {

            delete [] pData;

      }

 

      // Átmásoljuk a másik verem tartalmát

      if(theOther.elementNum==0)

      {

            elementNum=0;

            pData=NULL;

      }

      else

      {

            elementNum=theOther.elementNum;

            pData=new int[elementNum];

            for(unsigned int i=0;i<elementNum;i++)

            {

                  pData[i]=theOther.pData[i];

            }

      }

      return *this;

}

 

void Stack::pop(int& element)

{

      if(elementNum==0)

      {

            throw stack_exception("Data request from empty stack.");

            return;

      }

 

      if(elementNum==1)

      {

            element=pData[0];

            delete []pData;

            pData=NULL;

            elementNum=0;

            return;

      }

 

      elementNum--;

      element=pData[elementNum];

      int* pTemp=new int[elementNum];

 

      for(unsigned int i=0;i<elementNum;i++)

      {

            pTemp[i]=pData[i];

      }

      delete[] pData;

      pData=pTemp;

 

}

 

void Stack::push(int element)

{

      // C++-ban az UINT_MAX helyett a limits headerben található

      // numeric_limits sablont használjuk a maximális unsigned int érték

      // lekérdezésére

      if(elementNum==numeric_limits<unsigned int>::max())

      {

            throw stack_exception("Stack is full.");

            return;

      }

 

      int* pTemp=new int[elementNum+1];

 

      for(unsigned int i=0; i<elementNum;i++)

      {

            pTemp[i]=pData[i];

      }

 

      pTemp[elementNum]=element;

 

      if(pData)delete[]pData;

      pData=pTemp;

      elementNum++;

}

 

void Stack::readBinary(std::istream& is)

{

      // Figyeljük meg a "mindent vagy semmit" megközelítést:

      // csak akkor változtatjuk az objektum állapotát, ha minden sikerült.

      // Csinálhatnánk egy ideiglenes veremmel, de az lassabb lenne, mert elemenként

      // tudnánk csak beolvasni.

 

      unsigned int elementNum;

 

      is.read((char*) &elementNum, sizeof(elementNum));

      if(!is)

            return;

 

      if(elementNum == 0)

      {

            // Töröljük az előzőt

            delete pData;

            pData = NULL;

            return;

      }

 

      int* pTemp = new int [elementNum];

      is.read((char*)pTemp, sizeof(pTemp[0])*elementNum);

 

 

      // Csak akkor változtatjuk meg a verem állapotát, ha a beolvasás sikeres volt.

      // Így tartjuk fenn a konzisztenciát.

      if(is)

      {

            // Töröljük a dinamikus adatterületet         

            delete [] pData;

 

            this->elementNum = elementNum;

            pData = pTemp;

      }

      else

      {

            // Ha nem sikerült az elemek beolvasása, akkor töröljük az ideiglenes változót

            delete[] pTemp;

      }

}

 

void Stack::writeBinary(std::ostream& os)const

{

      // Először kiírjuk, hány elem van, utána pedig az elemek következnek

      os.write((const char*)&elementNum,sizeof(elementNum));

      os.write((const char*)pData,sizeof(pData[0])*elementNum);

}

 

void Stack::readText(std::istream& is)

{

      // Ideiglenes verem: ha hiba van, akkor nem módosítjuk az objektum állapotát

      Stack s;

 

      int elem;

      while(is >> elem)

      {

            s.push(elem);

      }

 

      if(is.eof()) // Ha hiba van, de az eof

      {

            *this = s;

            is.clear(ios::eofbit); // A hibát töröljük, az EOF állapotot nem

      }

}

 

void Stack::writeText(std::ostream& os)const

{

      for(unsigned int i=0; i<elementNum;i++)

      {

            os << ' ' << pData[i];

      }

}


A StackTest.cpp állomány:

#include <iostream>

#include <fstream>

#include "Stack.h"

 

using namespace std;

 

void main(void)

{

      Stack s1;

      s1.push(1);

      s1.push(2);

      s1.push(3);

 

 

      try

      {

            // Beolvasás tesztelése

            // EOF: Windows: <Enter>Ctrl+Z<Enter>, Linux: Ctrl+D <Enter>

            cout << "Stack element, separated with spaces, ending with EOF): ";

            s1.readText(cin);

            if(cin)

            {

                  s1.writeText(cout);

                  cout << endl;

            }

            else

            {

                  cerr << "Error reading stack." << endl;

            }

 

 

            // Tesztelés állományokkal

            // (a destruktor lezárja az állományt, csak akkor zárjuk le a close tagfüggvénnyel,

            // ha az állományt megakarjuk nyitni.)

 

            // 1. Kiírás bináris állományba

            ofstream outFileBinary("stack.bin", ios::out|ios::binary);

            s1.writeBinary(outFileBinary);

            outFileBinary.close();

 

            // 2. Beolvasás bináris állományból

            ifstream inFileBinary ("stack.bin", ios::in|ios::binary);

            Stack s2;

            s2.readBinary(inFileBinary);

            if(inFileBinary)

            {

                  s2.writeText(cout); cout << endl;

            }

            else

            {

                  cerr << "Error reading stack." << endl;

            }

 

 

            // 3. Kiírás szöveges állományba

            ofstream outFileText("stack.txt", ios::out);

            s1.writeText(outFileText);

            outFileText.close();

 

            // 4. Beolvasás szöveges állományból

            ifstream inFileText("stack.txt", ios::in);

            s2.readText(inFileText);

 

            if(inFileText)

            {

                  s2.writeText(cout); cout << endl;

            }

            else

            {

                  cerr << "Error reading stack." << endl;

            }

      }

      catch(const stack_exception& e) // Elkapjuk a Stack kivételeit

      {

            cout << e.what() << endl;

      }

}

 

 

 




2008.01.15. 0:26:31 |  Permalink  |  Hozzászólások száma: 0  |  Tárgyszavak: Állományok kezelése


Írja meg Ön is véleményét!


Hozzászólásokat csak regisztrált, bejelentkezett felhasználóktól tudunk elfogadni!

Hozzászólások