Commit 84d6c920 by Szeberényi Imre

v0

parents
#
# Makefile pelda a pstring feladat megoldasanak forditasara
# gnumake valtozat
# Linuxokon es ural2-n is elerheto
#
PROG = pstring_test # a program neve (ezt allitjuk elo)
PROG_O = string5.o pstring.o pstring_test.o # program object fajljai
PROG_H = string5.h pstring.h searializable.h # program header fajljai
PROG_L = # program libjei
MTRACE_O = memtrace.o # memtrace object fajl
MTRACE_H = memtrace.h # memtrace es memcheck header fajlja
CXX = g++ # a C fordito neve
#CXX = clang++ # clang-ot (llvm) is erdemes kiprobalni
CXXFLAGS = -pedantic -Wall -Werror # kapcsolok: legyen bobeszedu es pedans
CXXFLAGS += -ggdb -DMEMTRACE # es legyen debug info is
LDFLAGS = -ggdb # debug a linkelesnel
# osszes object, osszes header osszes lib
OBJS = $(PROG_O) $(MTRACE_O)
HEADS = $(PROG_H) $(MTRACE_H)
LIBS = $(PROG_L)
# alapertelmezett cel: program
.PHONY: all
all: $(PROG)
$(PROG): $(OBJS)
$(CXX) $(LDFLAGS) $(OBJS) -o $@ $(LIBS)
# feltetelezzuk, hogy az osszes obj fugg az osszes headertol
$(OBJS): $(HEADS)
# takaritas igeny szerint
.PHONY: clean
clean:
rm -f $(OBJS) $(PROG)
A korábban elkészített **String** és az előadáson bemutatott **Serializable** osztályok **felhasználásával** készítsen egy **PString** osztályt, ami **kompatibilis** a String osztállyal és pontosan ugyanúgy használható, mint a **String** osztály azzal a különbséggel, hogy példányai
perzisztens viselkedésre is képesek. Azaz képesek egy adatfolyamra kiírni belső állapotukat és arról visszaolvasva visszaállítani azt.
A **PString** osztály legyen kompatibilis a **Serializable** osztállyal is!
A **String** osztály teszteléséhez hasonló teszteseteket készítettünk *(pstring_test.cpp)*,
amiben feltételezzük, hogy létezik a következő két metódus:
* void PString::write(std::ostream&) - a paraméterként kapott adatfolyamra kimenti a belső állapotát
* void PString::read(std::istream&) - a paraméterként kapott adatfolyamról visszaállítja a belső állapotát
**Feladatok:**
- Töltse le az előkészített projektet:
[https://git.ik.bme.hu/Prog2/ell_feladat/PString](https://git.ik.bme.hu/Prog2/ell_feladat/PString)
- Készítse el a **PString** osztályt a *pstring.h* és az *pstring.cpp* állományokban!
Ügyeljen arra, hogy a **PString** osztály példányai minden tesztesetben használhatóak legyenek, ahol a **String** osztály példányai használhatók! Öröklés esetén ezt a kompatibilitás garantálja, de ez nem biztos, hogy elegendő. Egyes műveletekben keletkező eredmény típusa ugyanis String, amit viszont át kell alakítani **PString** példánnyá. (Működnie kell a típuskonverziónak a *String* és a *Pstring* között mindkét irányban.)
- Tesztelje a megadott tesztprogrammal az új osztályt! Az egyes tesztek futása a korábban megismert **ELKESZULT** makró segítségével szabályozható. (Az új funkciók tesztjei a 12 -14 értéknél futnak.) **Érdemes 0 értékkel kezdeni**. Ezt követően már lehet bátran 14-re állítani!
- Figyelje meg a 12. és 14. teszteset által kiírt memóriatartalmat (dump). Ez segíthet a hibakeresésben.
5. Amennyiben a tesztek jól futnak, töltse fel a *JPorta* feladatbeadó rendszerbe az **pstring.h** és a **pstring.cpp** fájlokat!
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
/*********************************
Memoriaszivargas-detektor
Keszitette: Peregi Tamas, BME IIT, 2011
petamas@iit.bme.hu
Kanari: Szeberenyi Imre, 2013.,
VS 2012: Szeberényi Imre, 2015.,
mem_dump: 2016.
inclue-ok: 2017., 2018. 2019.
*********************************/
#ifndef MEMTRACE_H
#define MEMTRACE_H
#if defined(MEMTRACE)
/*ha definiálva van, akkor a hibakat ebbe a fajlba írja, egyébkent stderr-re*/
/*#define MEMTRACE_ERRFILE MEMTRACE.ERR*/
/*ha definialva van, akkor futas kozben lancolt listat epit. Javasolt a hasznalata*/
#define MEMTRACE_TO_MEMORY
/*ha definialva van, akkor futas kozben fajlba irja a foglalasokat*/
/*ekkor nincs ellenorzes, csak naplozas*/
/*#define MEMTRACE_TO_FILE*/
/*ha definialva van, akkor a megallaskor automatikus riport keszul */
#define MEMTRACE_AUTO
/*ha definialva van, akkor malloc()/calloc()/realloc()/free() kovetve lesz*/
#define MEMTRACE_C
#ifdef MEMTRACE_C
/*ha definialva van, akkor free(NULL) nem okoz hibat*/
#define ALLOW_FREE_NULL
#endif
#ifdef __cplusplus
/*ha definialva van, akkor new/delete/new[]/delete[] kovetve lesz*/
#define MEMTRACE_CPP
#endif
#if defined(__cplusplus) && defined(MEMTRACE_TO_MEMORY)
/*ha definialva van, akkor atexit helyett objektumot hasznal*/
/*ajanlott bekapcsolni*/
#define USE_ATEXIT_OBJECT
#endif
/******************************************/
/* INNEN NE MODOSITSD */
/******************************************/
#ifdef NO_MEMTRACE_TO_FILE
#undef MEMTRACE_TO_FILE
#endif
#ifdef NO_MEMTRACE_TO_MEMORY
#undef MEMTRACE_TO_MEMORY
#endif
#ifndef MEMTRACE_AUTO
#undef USE_ATEXIT_OBJECT
#endif
#ifdef __cplusplus
#define START_NAMESPACE namespace memtrace {
#define END_NAMESPACE } /*namespace*/
#define TRACEC(func) memtrace::func
#include <new>
#else
#define START_NAMESPACE
#define END_NAMESPACE
#define TRACEC(func) func
#endif
// THROW deklaráció változatai
#if defined(_MSC_VER)
// VS rosszul kezeli az __cplusplus makrot
#if _MSC_VER < 1900
// * nem biztos, hogy jó így *
#define THROW_BADALLOC
#define THROW_NOTHING
#else
// C++11 vagy újabb
#define THROW_BADALLOC noexcept(false)
#define THROW_NOTHING noexcept
#endif
#else
#if __cplusplus < 201103L
// C++2003 vagy régebbi
#define THROW_BADALLOC throw (std::bad_alloc)
#define THROW_NOTHING throw ()
#else
// C++11 vagy újabb
#define THROW_BADALLOC noexcept(false)
#define THROW_NOTHING noexcept
#endif
#endif
START_NAMESPACE
int allocated_blocks();
END_NAMESPACE
#if defined(MEMTRACE_TO_MEMORY)
START_NAMESPACE
int mem_check(void);
END_NAMESPACE
#endif
#if defined(MEMTRACE_TO_MEMORY) && defined(USE_ATEXIT_OBJECT)
#include <cstdio>
START_NAMESPACE
class atexit_class {
private:
static int counter;
static int err;
public:
atexit_class() {
#if defined(CPORTA) && !defined(CPORTA_NOSETBUF)
if (counter == 0) {
setbuf(stdout, 0);
setbuf(stderr, 0);
}
#endif
counter++;
}
int check() {
if(--counter == 0)
err = mem_check();
return err;
}
~atexit_class() {
check();
}
};
static atexit_class atexit_obj;
END_NAMESPACE
#endif/*MEMTRACE_TO_MEMORY && USE_ATEXIT_OBJECT*/
/*Innentol csak a "normal" include eseten kell, kulonben osszezavarja a mukodest*/
#ifndef FROM_MEMTRACE_CPP
#include <stdlib.h>
#ifdef __cplusplus
#include <iostream>
/* ide gyűjtjük a nemtrace-vel összeakadó headereket, hogy előbb legyenek */
#include <fstream> // VS 2013 headerjében van deleted definició
#include <sstream>
#include <vector>
#include <list>
#include <map>
#include <algorithm>
#include <functional>
#endif
#ifdef MEMTRACE_CPP
namespace std {
typedef void (*new_handler)();
}
#endif
#ifdef MEMTRACE_C
START_NAMESPACE
#undef malloc
#define malloc(size) TRACEC(traced_malloc)(size,#size,__LINE__,__FILE__)
void * traced_malloc(size_t size, const char *size_txt, int line, const char * file);
#undef calloc
#define calloc(count,size) TRACEC(traced_calloc)(count, size, #count","#size,__LINE__,__FILE__)
void * traced_calloc(size_t count, size_t size, const char *size_txt, int line, const char * file);
#undef free
#define free(p) TRACEC(traced_free)(p, #p,__LINE__,__FILE__)
void traced_free(void * p, const char *size_txt, int line, const char * file);
#undef realloc
#define realloc(old,size) TRACEC(traced_realloc)(old,size,#size,__LINE__,__FILE__)
void * traced_realloc(void * old, size_t size, const char *size_txt, int line, const char * file);
void mem_dump(void const *mem, size_t size, FILE* fp);
END_NAMESPACE
#endif/*MEMTRACE_C*/
#ifdef MEMTRACE_CPP
START_NAMESPACE
#undef set_new_handler
#define set_new_handler(f) TRACEC(_set_new_handler)(f)
void _set_new_handler(std::new_handler h);
void set_delete_call(int line, const char * file);
END_NAMESPACE
void * operator new(size_t size, int line, const char * file) THROW_BADALLOC;
void * operator new[](size_t size, int line, const char * file) THROW_BADALLOC;
void * operator new(size_t size) THROW_BADALLOC;
void * operator new[](size_t size) THROW_BADALLOC;
void operator delete(void * p) THROW_NOTHING;
void operator delete[](void * p) THROW_NOTHING;
/* Visual C++ 2012 miatt kell, mert háklis, hogy nincs megfelelő delete, bár senki sem használja */
void operator delete(void *p, int, const char *) THROW_NOTHING;
void operator delete[](void *p, int, const char *) THROW_NOTHING;
#define new new(__LINE__, __FILE__)
#define delete memtrace::set_delete_call(__LINE__, __FILE__),delete
#ifdef CPORTA
#define system(...) // system(__VA_ARGS__)
#endif
#endif /*MEMTRACE_CPP*/
#endif /*FROM_MEMTRACE_CPP*/
#endif /*MEMCHECK*/
#endif /*MEMTRACE_H*/
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CodeBlocks_project_file>
<FileVersion major="1" minor="6" />
<Project>
<Option title="pstring" />
<Option pch_mode="2" />
<Option compiler="gcc" />
<Build>
<Target title="Debug">
<Option output="bin/Debug/perziszt" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Debug/" />
<Option type="1" />
<Option compiler="gcc" />
<Compiler>
<Add option="-g" />
<Add option="-DMEMTRACE" />
</Compiler>
</Target>
<Target title="Release">
<Option output="bin/Release/perziszt" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Release/" />
<Option type="1" />
<Option compiler="gcc" />
<Compiler>
<Add option="-O2" />
</Compiler>
<Linker>
<Add option="-s" />
</Linker>
</Target>
</Build>
<Compiler>
<Add option="-pedantic" />
<Add option="-Wall" />
<Add option="-Werror" />
</Compiler>
<Unit filename="gtest_lite.h" />
<Unit filename="memtrace.cpp" />
<Unit filename="memtrace.h" />
<Unit filename="pstring_test.cpp" />
<Unit filename="serializable.h" />
<Unit filename="string5.cpp" />
<Unit filename="string5.h" />
<Extensions>
<code_completion />
<envvars />
<debugger />
<lib_finder disable_auto="1" />
</Extensions>
</Project>
</CodeBlocks_project_file>
#ifndef SERIALIZABLE_H
#define SERIALIZABLE_H
#include <iostream>
struct Serializable {
virtual void write(std::ostream &) const {}
virtual void read(std::istream &) {}
virtual ~Serializable() {}
};
#endif // SERIALIZABLE_H
/**
*
* \file string5.cpp
*
*/
#ifdef _MSC_VER
// MSC ne adjon figyelmeztető üzenetet a stringkezelő függvényekre.
#define _CRT_SECURE_NO_WARNINGS
#endif
#include <iostream> // Kiíratáshoz
#include <cstring> // Stringműveletekhez
#include "memtrace.h" // a standard headerek után kell lennie
#include "string5.h"
using std::cin;
using std::ios_base;
/// Konstruktor: egy char karakterből (createStrFromChar)
String::String(char ch) {
// Meghatározzuk a hosszát
len = 1;
// Lefoglalunk a helyet a hossznak + a lezaró nullának
pData = new char[len+1];
// Betesszük a karaktert
pData[0] = ch;
pData[1] = '\0';
}
// Konstruktor: egy nullával lezárt char sorozatból (createStringFromCharStr)
String::String(const char *p) {
// Meghatározzuk a hosszát
len = strlen(p);
// Helyet foglalunk
pData = new char[len+1];
// Bemásoljuk a stringet, ami le van zárva 0-val így használható az strcpy is
strcpy(pData, p);
}
// Másoló konstruktor
String::String(const String& s1) {
// Meghatározzuk a hosszát
len = s1.len;
// Helyet foglalunk
pData = new char[len+1];
// Bemásoljuk a stringet, ami le van zárva 0-val így használható az strcpy is
strcpy(pData, s1.pData);
}
// operator=
String& String::operator=(const String& rhs_s) {
if (this != &rhs_s) {
delete[] pData;
len = rhs_s.len;
// Helyet foglalunk
pData = new char[len+1];
// Bemásoljuk a stringet, ami le van zárva 0-val így használható az strcpy is
strcpy(pData, rhs_s.pData);
}
return *this;
}
// [] operátorok: egy megadott indexű elem REFERENCIÁJÁVAL térnek vissza.
// indexhiba esetén dobjon egy const char * típusú hibát!
char& String::operator[](unsigned int idx) {
if (idx >= len) throw "String: indexelesi hiba";
return pData[idx];
}
const char& String::operator[](unsigned int idx) const {
if (idx >= len) throw "String: indexelesi hiba";
return pData[idx];
}
// + operátor, ami két stringet ad össze (concatString)
String String::operator+(const String& rhs_s) const {
String temp; // ide kerül az eredmény
// Meghatározza az új string hosszát
temp.len = len + rhs_s.len;
// Felszabadítja a temp adattaerületét
delete []temp.pData;
// lefoglalja a memóriát az új stringnek.
temp.pData = new char[temp.len+1];
// Az elejére bemásolja az első stringet
strcpy(temp.pData, pData);
// Bemásolja a második stringet.
strcat(temp.pData, rhs_s.pData);
return temp; // visszatér az eredménnyel
}
// << operator, ami kiír az ostream-re
std::ostream& operator<<(std::ostream& os, const String& s0) {
os << s0.c_str();
return os;
}
// << operátor, ami beolvas az istreamről egy szót
std::istream& operator>>(std::istream& is, String& s0) {
unsigned char ch;
s0 = String(""); // üres string, ehhez fűzünk hozzá
std::ios_base::fmtflags fl = is.flags(); // eltesszük a régi flag-eket
is.setf(ios_base::skipws); // az elején eldobjuk a ws-t
while (is >> ch) {
is.unsetf(ios_base::skipws); // utána pedig már nem
if (isspace(ch)) {
is.putback(ch); // na ezt nem kérjük
break;
} else {
s0 = s0 + ch; // végére fűzzük a karaktert
}
}
is.setf(fl); // visszaállítjuk a flag-eket
return is;
}
#ifndef STRING_H
#define STRING_H
/**
* \file string5.h
*
* Ez a fájl tartalmazza a String osztály deklarációját és inline függvényeit.
*/
#include <iostream>
/**
* String osztály.
* A pData-ban vannak a karakterek (a lezáró nullával együtt),
* len a hossz.A hosszba nem számít bele a lezáró nulla.
*/
class String {
char *pData; ///< pointer az adatra
size_t len; ///< hossz lezáró nulla nélkül
public:
/// Hossz lekérdezése.
/// @return Sztring hossza
size_t size() const { return len; }
/// Default konstruktor
/// String() :pData(0), len(0) {}
/// helyett ""-val inicializáljuk a const char*-osban
/// C-sztringet ad vissza
/// @return pinter egy '\0'-val lezárt (C) sztringre
const char* c_str() const { return pData;}
/// Konstruktor egy char karakterből
/// @param ch - karakter
String(char ch);
/// Konstruktor egy nullával lezárt char sorozatból
/// Ez a deafault is!
/// @param p - pointer egy C sztringre
String(const char *p = "");
/// Másoló konstruktor
/// @param s1 - String, amiből létrehozzuk az új String-et
String(const String& s1);
/// Destruktor
virtual ~String() { delete[] pData; }
/// Kiírunk egy Stringet (debug célokra)
/// Előtte kiírunk egy tetszőleges szöveget.
/// @param txt - nullával lezárt szövegre mutató pointer
void printDbg(const char *txt = "") const {
std::cout << txt << "[" << len << "], "
<< (pData ? pData : "(NULL)") << std::endl;
}
/// Értékadó operátor.
/// @param rhs_s - jobboldali String
/// @return baoldali (módosított) string (referenciája)
String& operator=(const String& rhs_s);
/// Két Stringet összefűz
/// @param rhs_s - jobboldali String
/// @return új String, ami tartalmazza a két stringet egmás után
String operator+(const String& rhs_s) const ;
/// Sztrinhez karaktert összefűz
/// @param rhs_c - jobboldali karakter
/// @return új String, ami tartalmazza a sztringet és a karaktert egymás után
String operator+(char rhs_c) const { return *this + String(rhs_c);}
/// A string egy megadott indexű elemének REFERENCIÁJÁVAL tér vissza.
/// @param idx - charakter indexe
/// @return karakter (referencia)
/// Indexelési hiba esetén const char* kivételt dob.
char& operator[](unsigned int idx);
/// A string egy megadott indexű elemének REFERENCIÁJÁVAL tér vissza.
/// @param idx - karakter indexe
/// @return karakter (referencia)
/// Indexelési hiba esetén const char* kivételt dob (assert helyett).
const char& operator[](unsigned int idx) const;
};
/// Globális függvények:
/// kiír az ostream-re
/// @param os - ostream típusú objektum
/// @param s0 - String, amit kiírunk
/// @return os
std::ostream& operator<<(std::ostream& os, const String& s0);
/// Beolvas az istream-ről egy szót egy string-be.
/// @param is - istream típusú objektum
/// @param s0 - String, amibe beolvas
/// @return is
std::istream& operator>>(std::istream& is, String& s0);
/// Karakterhez sztringet fűz
/// @param ch - karakter
/// @param str - String
/// @return új String, ami tartalmazza a karaktert és a sztringet egymás után
inline String operator+(char ch, const String& str) { return String(ch) + str; }
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment