Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- TYO4.CC
- //----------------------------------------------------------//
- //OHJ2 syksy 2013 //
- //HARJOITUSTYO4, TEEMU LAINE, 234210, <teemu.laine@tut.fi> //
- //MODUULIT: //
- //tyo4.cc 1.9 //
- //todolista.cc 1.4 //
- //todolista.hh 1.3 //
- //tehtavat.cc 1.6 //
- //tehtavat.hh 1.3 //
- //----------------------------------------------------------//
- //Ohjeessa ei maaritelty tarkkaan, annetaanko virheilmoitus vai ei
- //jos todo-lista on tyhja _JA_ maaritelty ja kaytetaan esim
- //"seuraava"-komentoa, tassa ohjelmassa edellamainitusta ei tapahdu
- //mitaan, kysytaan vain uutta komentoa
- //- - - - - - - - - - - - - - - - - - -
- //VIRHEET (omaa kirjanpitoa)
- //komentoriviparametrit[x]
- //syotetiedosto ei aukea[x]
- //syotetiedostossa virhe[x]
- //muistinvaraus epäonnistui[x]
- //tallentaminen epäonnistui[x]
- //muut
- //segmentation fault kun ei tärkeyksiä jälellä x
- //komennot jossa käytetään dequea, varmista että solu olemassa x
- //outofrange tyhjalla x
- //*lue*, muista tyhjennys x
- //listaa ei maaritelty x
- //seuraava kaatuu jos tyhjä mutta alustettu x
- //- - - - - - - - - - - - - - - - - - - -
- #include <iostream>
- #include <fstream>
- #include <deque>
- #include <string>
- #include <OHJ-1150>
- using namespace std;
- //MODUULIT
- #include "todolista.hh"
- #include "tehtavat.hh"
- //lue() - paluuarvo:
- //1=kaikki ok
- //2=lista on maarittelematon
- //3=ohjelmansuoritus loppuu
- unsigned lue(const string& syote, Todolista& lista)
- {
- ifstream virtatiedosto(syote.c_str());
- //Tiedosto ei avaudu
- if(! virtatiedosto)
- {
- cerr << "Virhe: syotetiedostoa ei saa avattua luettavaksi" << endl;
- return 3;
- }
- string rivi;
- bool ensimmainen = false;
- unsigned kiireellisyyksia = 0;
- while(getline(virtatiedosto, rivi))
- {
- if(! ensimmainen)//ensimmainen rivi - numero ylos
- {
- if(ohj2::string_luvuksi(rivi, kiireellisyyksia))
- {
- lista.prioriteetteja(kiireellisyyksia);
- ensimmainen = true;
- continue;
- }
- else
- {
- cerr << "Virhe: virheellinen tiedoston rivi \""
- << rivi << "\"." << endl;
- virtatiedosto.close();
- return 2;
- }
- }
- deque<string> riviosat;
- ohj2::paloittele_string(rivi, ':', riviosat);
- //whitespacet pois numerosta
- unsigned tarkeys = 0;
- string tarkeys_str = riviosat.at(0);
- ohj2::poista_valit_alusta_ja_lopusta(tarkeys_str);
- //lisätään luokkaan
- if(ohj2::string_luvuksi(tarkeys_str, tarkeys))
- {
- //liian suuri tarkeys
- if(tarkeys >= kiireellisyyksia)
- {
- cerr << "Virhe: virheellinen tiedoston rivi \""
- << rivi << "\"." << endl;
- lista.Alusta();
- virtatiedosto.close();
- return 2;
- }
- //whitespacet pois tehtavasta
- string tehtava = riviosat.at(1);
- ohj2::poista_valit_alusta_ja_lopusta(tehtava);
- if(! lista.lisaa_tehtava(tarkeys, tehtava))
- {
- virtatiedosto.close();
- return 3;
- }
- }
- else
- {
- cerr << "Virhe: virheellinen tiedoston rivi \""
- << rivi << "\"." << endl;
- lista.Alusta();
- virtatiedosto.close();
- return 2;
- }
- }
- virtatiedosto.close();
- return 1;
- }
- //tarkistetaan ettei dequella ole virheellista maaraa soluja
- //ja valtytaan outofrangeista
- bool dequetarkistus(const deque<string>& osat)
- {
- if(osat.empty())
- return true;
- if(osat.at(0) == "seuraava" and osat.size() != 1) return true;
- if(osat.at(0) == "poista" and osat.size() != 1) return true;
- if(osat.at(0) == "lisaa" and osat.size() != 3) return true;
- if(osat.at(0) == "tulosta" and osat.size() != 1) return true;
- if(osat.at(0) == "uusi" and osat.size() != 2) return true;
- if(osat.at(0) == "lue" and osat.size() != 2) return true;
- if(osat.at(0) == "tallenna" and osat.size() != 2) return true;
- if(osat.at(0) == "siirra" and osat.size() != 3) return true;
- if(osat.at(0) == "loppu" and osat.size() != 1) return true;
- return false;
- }
- int main(int argc, char* argv[])
- {
- Todolista lista;
- bool onkoalustettu = false;
- if(argc == 2)
- {
- unsigned paluu = lue(string(argv[1]), lista);
- if(paluu == 3)
- {
- return 0;
- }
- if(paluu == 1)
- {
- onkoalustettu = true;
- }
- }
- else if(argc != 1)
- {
- cerr << "Virhe: vaara maara komentoparametreja." << endl;
- return 0;
- }
- string syote;
- deque<string> osat;
- //komentorivi alkaa
- while(1)
- {
- cout << "todo> ";
- getline(cin, syote);
- ohj2::paloittele_komento(syote, osat);
- //varmistetaan dequen oikeellisuus
- if(dequetarkistus(osat))
- {
- cerr << "Virhe: ongelma kayttajan syottaman komennon kanssa." <<endl;
- continue;
- }
- //KAYTTAJAN KOMENNOT
- //------------------
- if(osat.at(0) == "seuraava" and onkoalustettu)
- {
- if(lista.size() == 0)
- continue;
- lista.seuraava();
- }
- //------------------
- else if(osat.at(0) == "poista" and onkoalustettu)
- {
- if(lista.size() == 0)
- continue;
- lista.seuraava(true);
- }
- //------------------
- else if(osat.at(0) == "lisaa" and onkoalustettu)
- {
- unsigned tarkeys = 0;
- if(ohj2::string_luvuksi(osat.at(1), tarkeys))
- {
- //vaara tarkeystaso
- if(tarkeys >= lista.tasomaara())
- {
- cerr << "Virhe: ongelma kayttajan "
- << "syottaman komennon kanssa." <<endl;
- continue;
- }
- if(! lista.lisaa_tehtava(tarkeys, osat.at(2)))
- {
- return 0;
- }
- }
- else
- {
- cerr << "Virhe: ongelma kayttajan "
- << "syottaman komennon kanssa." <<endl;
- continue;
- }
- }
- //------------------
- else if(osat.at(0) == "tulosta" and onkoalustettu)
- {
- if(lista.size() == 0)
- continue;
- lista.tulosta_tehtavat();
- }
- //------------------
- else if(osat.at(0) == "uusi")
- {
- lista.Alusta();
- unsigned kiireellisyyksia = 0;
- if(ohj2::string_luvuksi(osat.at(1), kiireellisyyksia))
- {
- lista.prioriteetteja(kiireellisyyksia);
- }
- else
- {
- cerr << "Virhe: ongelma kayttajan "
- << "syottaman komennon kanssa." <<endl;
- continue;
- }
- onkoalustettu = true;
- }
- //------------------
- else if(osat.at(0) == "lue")
- {
- lista.Alusta();
- unsigned paluu = lue(osat.at(1), lista);
- if(paluu == 3)
- {
- return 0;
- }
- if(paluu == 2)
- {
- onkoalustettu = false;
- }
- else if(paluu == 1)
- {
- onkoalustettu = true;
- }
- }
- //------------------
- else if(osat.at(0) == "tallenna" and onkoalustettu)
- {
- if(! lista.tallenna(osat.at(1)))
- {
- cerr << "Virhe: tallennus epaonnistui." << endl;
- continue;
- }
- }
- //------------------
- else if(osat.at(0) == "siirra" and onkoalustettu)
- {
- if(lista.size() == 0)
- continue;
- unsigned tehtavanro, taso;
- string tehtavaX;
- if(ohj2::string_luvuksi(osat.at(1), tehtavanro) &&
- ohj2::string_luvuksi(osat.at(2), taso) &&
- lista.siirra(tehtavanro, tehtavaX))
- {
- if(taso >= lista.tasomaara())
- {
- cerr << "Virhe: ongelma kayttajan "
- << "syottaman komennon kanssa." <<endl;
- continue;
- }
- if(! lista.lisaa_tehtava(taso, tehtavaX))
- {
- return 0;
- }
- }
- else
- {
- cerr << "Virhe: ongelma kayttajan "
- << "syottaman komennon kanssa." <<endl;
- continue;
- }
- }
- //------------------
- else if(osat.at(0) == "loppu")
- {
- break;
- }
- //------------------
- else
- {
- cerr << "Virhe: ongelma kayttajan syottaman komennon kanssa." <<endl;
- continue;
- }
- }
- }
- // $Log: tyo4.cc,v $
- // Revision 1.9 2013/12/19 14:05:14 lainet
- // tiedostonluvun semanttiset virheet done
- //
- // Revision 1.8 2013/12/19 12:50:28 lainet
- // try-catch linkitetty mainiin muistinvarausongelmille
- //
- // Revision 1.7 2013/12/18 16:53:30 lainet
- // ei pitaisi tulla out_of_rangeja enaa vaaranlaisella komennolla
- //
- // Revision 1.6 2013/12/18 15:45:10 lainet
- // siirra() lisatty
- //
- // Revision 1.5 2013/12/13 12:23:54 lainet
- // whitespacen poisto lisatty lukuun
- //
- // Revision 1.4 2013/12/05 12:28:31 lainet
- // tallennus toimii
- //
- // Revision 1.3 2013/12/04 12:25:29 lainet
- // "tallenna" ja "siirra" lukuunottamatta toiminnot toimivat paapiirteittain hyvin, muutamasta kohtaa herjaa segmentation faultia
- //
- // Revision 1.2 2013/12/02 21:32:57 lainet
- // alkeellinen tiedostonluku tehty
- //
- // Revision 1.1 2013/12/02 18:56:34 lainet
- // Initial revision
- //
- ------------------------------------------------------------------------------------
- TODOLISTA.HH
- #ifndef TODOLISTA_HH
- #define TODOLISTA_HH
- #include <string>
- using namespace std;
- #include "tehtavat.hh"
- class Todolista
- {
- public:
- Todolista();
- void prioriteetteja(unsigned kiireellisyyksia);
- unsigned tasomaara();
- unsigned size();
- void seuraava(bool poistetaanko = false);
- bool lisaa_tehtava(unsigned kiiretaso, const string& kuvaus);
- void tulosta_tehtavat();
- bool tallenna(const string& tiednimi);
- bool siirra(unsigned tehtavanro, string& tehtavaX);
- void Alusta();//"destructor"
- ~Todolista();
- private:
- struct Alkio
- {
- unsigned tarkeys;
- Tehtavat teht;
- Alkio* next;
- Alkio* prev;
- };
- Alkio* first;
- Alkio* last;
- unsigned kiireellisyystasoja;
- };
- #endif
- // $Log: todolista.hh,v $
- // Revision 1.3 2013/12/05 12:29:39 lainet
- // tallennus toimii
- //
- // Revision 1.2 2013/12/02 21:34:30 lainet
- // perustavanlaatuinen luokka Todolista tehty
- //
- // Revision 1.1 2013/12/02 18:57:28 lainet
- // Initial revision
- //
- -------------------------------------------------------------
- TODOLISTA.CC
- #include <string>
- #include <iostream>
- #include <fstream>
- using namespace std;
- #include "todolista.hh"
- #include "tehtavat.hh"
- //rakentaja
- Todolista::Todolista():
- first(nullptr),
- last(nullptr),
- kiireellisyystasoja(0)
- {}
- void Todolista::prioriteetteja(unsigned kiireellisyyksia)
- {
- kiireellisyystasoja = kiireellisyyksia;
- }
- unsigned Todolista::tasomaara()
- {
- return kiireellisyystasoja;
- }
- //palauttaa alkioiden määrän
- unsigned Todolista::size()
- {
- Alkio* laskija = first;
- unsigned alkioita = 0;
- while(laskija != nullptr)
- {
- laskija = laskija->next;
- alkioita++;
- }
- return alkioita;
- }
- //kayttajan komennot
- void Todolista::seuraava(bool poistetaanko)
- {
- //ei olemassa seuraavaa
- if(first == nullptr)
- {
- cerr << "Virhe: ongelma kayttajan syottaman komennon kanssa." << endl;
- }
- if(poistetaanko)
- {
- //true jos oli viimeinen teht kyseisessa alkiossa
- if(first->teht.tulosta(first->tarkeys, true, true))
- {
- //poistetaan nykyinen alkio, ainoa
- if(first == last)
- {
- last = nullptr;
- delete first;
- first = nullptr;
- }
- //poistetaan nykyinen alkio, vah. kaksi alkiota
- else
- {
- Alkio* poisto = first;
- first = first->next;
- first->prev = nullptr;
- delete poisto;
- poisto = nullptr;
- }
- }
- }
- else
- first->teht.tulosta(first->tarkeys, true);
- }
- bool Todolista::lisaa_tehtava(unsigned kiiretaso, const string& kuvaus)
- {
- //kokeillaan muistinvarausta
- try
- {
- Alkio* uusi = nullptr;
- if(first == nullptr) //tyhjä
- {
- uusi = new Alkio;
- first = last = uusi;
- uusi->tarkeys = kiiretaso;
- uusi->next = nullptr;
- uusi->prev = nullptr;
- }
- else//onko alussa tai lopussa
- {
- if(kiiretaso < first->tarkeys)//lisataan listan alkuun
- {
- uusi = new Alkio;
- uusi->next = first;
- uusi->prev = nullptr;
- first->prev = uusi;
- first = uusi;
- uusi->tarkeys = kiiretaso;
- }
- else if(kiiretaso > last->tarkeys)//lisataan viimeiseksi
- {
- uusi = new Alkio;
- uusi->next = nullptr;
- uusi->prev = last;
- last->next = uusi;
- last = uusi;
- uusi->tarkeys = kiiretaso;
- }
- else//tutkitaan vali
- {
- Alkio* seuraaja = first;
- while(seuraaja != nullptr)
- {
- if(kiiretaso == seuraaja->tarkeys)//loytyi jo ennestaan
- {
- uusi = seuraaja;
- break;
- }
- else if(kiiretaso > seuraaja->tarkeys and
- kiiretaso < seuraaja->next->tarkeys)
- //tulee nykyisen ja seuraavan valiin
- {
- uusi = new Alkio;
- uusi->prev = seuraaja;
- uusi->next = seuraaja->next;
- seuraaja->next->prev = uusi;
- seuraaja->next = uusi;
- uusi->tarkeys = kiiretaso;
- break;
- }
- seuraaja = seuraaja->next;
- }
- seuraaja = nullptr;
- }
- }
- //uusi nyt asettuneena oikeaan kiireystasoon
- uusi->teht.lisaa_solu(kuvaus);
- return true;
- }
- catch(...)
- {
- //muistinvaraus epaonnistui
- cerr << "Virhe: muistinvaraus epaonnistui." << endl;
- return false;
- }
- }
- void Todolista::tulosta_tehtavat()
- {
- Alkio* apu;
- apu = first;
- unsigned mones = 0;//pidetaan kirjaa mika jarjestysnumero
- while(apu != nullptr)
- {
- apu->teht.tulosta(apu->tarkeys, false, false, mones);
- mones += apu->teht.koko();
- apu = apu->next;
- }
- }
- bool Todolista::tallenna(const string& tiednimi)
- {
- //virta tiedoston tallennukseen
- ofstream otallennus(tiednimi);
- if(! otallennus)
- {
- return false;
- }
- otallennus << kiireellisyystasoja << endl;
- Alkio* tallennettava;
- tallennettava = first;
- while(tallennettava != nullptr)
- {
- //ostream&
- if(! tallennettava->teht.tallenna(otallennus, tallennettava->tarkeys))
- {
- return false;
- }
- tallennettava = tallennettava->next;
- }
- return true;
- }
- bool Todolista::siirra(unsigned tehtavanro, string& tehtavaX)
- {
- Alkio* apu = first;
- unsigned jnro = 0; //alkioittain summautuva jarjestysnumero
- while(apu != nullptr)
- {
- jnro += apu->teht.koko();
- if(tehtavanro <= jnro-1)
- {
- if(apu->teht.seek_and_destroy(
- (apu->teht.koko()-(jnro - tehtavanro)), tehtavaX))
- {
- //oli ainoa tehtava alkiossa, poistetaan
- //ensimmainen
- if(apu == first)
- {
- first = last = nullptr;
- delete apu;
- }
- //viimeinen
- else if(apu == last)
- {
- last->prev->next = nullptr;
- last = last->prev;
- delete apu;
- }
- else
- {
- //keskella
- apu->prev->next = apu->next;
- apu->next->prev = apu->prev;
- delete apu;
- }
- apu = nullptr;
- }
- return true;
- }
- apu = apu->next;
- }
- //liian suuri numero
- return false;
- }
- void Todolista::Alusta()//destructor
- {
- Alkio* tamanhetkinen = first;
- Alkio* loput = nullptr;
- last = nullptr;
- while(tamanhetkinen != nullptr)
- {
- loput = tamanhetkinen->next;
- delete tamanhetkinen;
- tamanhetkinen = loput;
- }
- first = nullptr;
- kiireellisyystasoja = 0;
- }
- Todolista::~Todolista()
- {
- Alkio* tamanhetkinen = first;
- Alkio* loput = nullptr;
- last = nullptr;
- while(tamanhetkinen != nullptr)
- {
- loput = tamanhetkinen->next;
- delete tamanhetkinen;
- tamanhetkinen = loput;
- }
- first = nullptr;
- }
- // $Log: todolista.cc,v $
- // Revision 1.4 2013/12/18 15:45:32 lainet
- // siirra() luotu
- //
- // Revision 1.3 2013/12/05 12:29:25 lainet
- // tallennus toimii
- //
- // Revision 1.2 2013/12/03 17:37:33 lainet
- // tehtavanlisays tarkeyden mukaan
- //
- // Revision 1.1 2013/12/02 18:57:13 lainet
- // Initial revision
- //
- -------------------------------------------------------------
- TEHTAVAT.HH
- #ifndef TEHTAVAT_HH
- #define TEHTAVAT_HH
- #include <string>
- using namespace std;
- class Tehtavat
- {
- public:
- Tehtavat();
- void lisaa_solu(const string& virke);
- unsigned koko();
- bool tulosta(unsigned tarkeys, bool vainyksi = false,
- bool poistetaanko = false, unsigned mones = 0);
- bool tallenna(ostream& otallennus, unsigned tarkeys);
- bool seek_and_destroy(unsigned monesko, string& tehtavaX);
- ~Tehtavat();
- private:
- struct Alkio
- {
- string kuvaus;
- Alkio* seuraava;
- };
- Alkio* ensimmainen;
- Alkio* viimeinen;
- };
- #endif
- // $Log: tehtavat.hh,v $
- // Revision 1.3 2013/12/05 12:29:09 lainet
- // tallennus toimii
- //
- // Revision 1.2 2013/12/02 19:04:10 lainet
- // luokka Tehtavat luotu
- //
- // Revision 1.1 2013/12/02 18:57:44 lainet
- // Initial revision
- //
- --------------------------------------------------------
- TEHTAVAT.CC
- #include <string>
- #include <iostream>
- #include <fstream>
- using namespace std;
- #include "tehtavat.hh"
- //rakentaja
- Tehtavat::Tehtavat():
- ensimmainen(nullptr),
- viimeinen(nullptr)
- {}
- void Tehtavat::lisaa_solu(const string& virke)
- {
- Alkio* uusi;
- uusi = new Alkio; //HUOMHUOM ei poistanut kaikkia
- if(ensimmainen == nullptr) //tyhjä
- {
- ensimmainen = viimeinen = uusi;
- }
- else
- {
- viimeinen->seuraava = uusi;
- viimeinen = uusi;
- }
- uusi->seuraava = nullptr;
- uusi->kuvaus = virke;
- }
- //palauttaa alkioiden määrän
- unsigned Tehtavat::koko()
- {
- Alkio* laskija = ensimmainen;
- unsigned alkioita = 0;
- while(laskija != nullptr)
- {
- laskija = laskija->seuraava;
- alkioita++;
- }
- return alkioita;
- }
- //jos vainyksi==true, komento ollut "seuraava"
- //jos poistetaanko==true, komento ollut "poista"
- bool Tehtavat::tulosta(unsigned tarkeys, bool vainyksi,
- bool poistetaanko, unsigned mones)
- {
- if(vainyksi)
- {
- cout << tarkeys << ":" << ensimmainen->kuvaus << endl;
- if(poistetaanko)
- {
- Alkio* poisto = ensimmainen;
- ensimmainen = ensimmainen->seuraava;
- if(ensimmainen == nullptr)
- {
- //vain yksi alkio
- delete poisto;
- viimeinen = nullptr;
- //poistetaan myos lista-alkio
- return true;
- }
- poisto->seuraava = nullptr;
- delete poisto;
- poisto = nullptr;
- }
- return false;
- }
- //koko sailon tulostus
- Alkio* apu = ensimmainen;
- while(apu != nullptr)
- {
- cout << "(" << mones << ") ";
- mones++;
- cout << tarkeys << ":" << apu->kuvaus << endl;
- apu = apu->seuraava;
- }
- return false;
- }
- bool Tehtavat::tallenna(ostream& otallennus, unsigned tarkeys)
- {
- Alkio* tallennettava = ensimmainen;
- while(tallennettava != nullptr)
- {
- otallennus << tarkeys << ":" << tallennettava->kuvaus << endl;
- if(! otallennus)
- {
- return false;
- }
- tallennettava = tallennettava->seuraava;
- }
- return true;
- }
- bool Tehtavat::seek_and_destroy(unsigned monesko, string& tehtavaX)
- {
- Alkio* apu = ensimmainen;
- for(unsigned i=0;i<monesko;i++)
- {
- apu = apu->seuraava;
- }
- //apu osoittaa nyt haluttuun alkioon
- tehtavaX = apu->kuvaus;
- //poisto
- if(ensimmainen == viimeinen)
- {
- //voidaan poistaa tarkeystaso
- apu = nullptr;
- return true;
- }
- if(apu == ensimmainen)
- {
- ensimmainen = ensimmainen->seuraava;
- delete apu;
- apu = nullptr;
- return false;
- }
- Alkio* edellinenptr = ensimmainen;
- for(unsigned i=1;i<monesko;i++)
- {
- edellinenptr = edellinenptr->seuraava;
- }
- if(apu == viimeinen)
- {
- //viimeinen alkio, poistetaan
- viimeinen = edellinenptr;
- viimeinen->seuraava = nullptr;
- delete apu;
- apu = nullptr;
- }
- else
- {
- //alkio keskella
- edellinenptr->seuraava = edellinenptr->seuraava->seuraava;
- delete apu;
- }
- apu = edellinenptr = nullptr;
- return false;
- }
- Tehtavat::~Tehtavat()
- {
- Alkio* tamanhetkinen = ensimmainen;
- Alkio* loput = nullptr;
- ensimmainen = viimeinen = nullptr;
- while(tamanhetkinen != nullptr)
- {
- loput = tamanhetkinen->seuraava;
- delete tamanhetkinen;
- tamanhetkinen = loput;
- }
- }
- // $Log: tehtavat.cc,v $
- // Revision 1.6 2013/12/19 14:28:36 lainet
- // poista-komennon ongelma poistettu jossa viimeisen alkion muisti ei poistunut
- //
- // Revision 1.5 2013/12/18 15:45:54 lainet
- // hae_ja_poista luotu
- //
- // Revision 1.4 2013/12/05 12:28:51 lainet
- // tallennus toimii
- //
- // Revision 1.3 2013/12/04 12:28:14 lainet
- // tulosta() kykenee parametreista riippuen joko tulostamaan kaikki, tulostamaan ensimmaisen tai tulostamaan ensimmaisen poistaen sen samalla
- //
- // Revision 1.2 2013/12/02 21:33:37 lainet
- // osaa lisätä ja tulostaa soluja, purkaja toimii myös
- //
- // Revision 1.1 2013/12/02 18:57:55 lainet
- // Initial revision
- //
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement