diff --git a/bane.cpp b/bane.cpp index b3cc2fea6fb211151bbb020edc898eddefb9f1c4..28a27142a985e2b39147824ad6e4b0b2a557bafe 100644 --- a/bane.cpp +++ b/bane.cpp @@ -12,47 +12,66 @@ using namespace std; /** - * Bane() Nullstiller alle datamedlemmer. Faktisk innlesning skjer i lesData + * Oppretter en ny Bane. Nullstiller alle dens datamedlemmer. + * Faktisk innlesning av reelle verdier skjer i lesData() + * + * @see Rute::Rute() */ Bane::Bane() { antVogner = lengde = 0; } -//TODO: Fyll på mer her etter som header-fila tar form +/** + * Oppretter en ny Bane fra fil. Leser inn dens datamedlemmer + * + * @param inn Filen det leses fra + * @see Rute::Rute(...) + */ Bane::Bane(ifstream & inn) : Rute (inn) { - inn >> antVogner >> lengde; inn.ignore(); + // Leser inn antall vogner på banen og lengden på banesettet: + inn >> antVogner >> lengde; inn.ignore(); // Forkaster '\n' } /** - * lesData() + * Leser inn alle datamedlemmer for en bane (virtuell) + * + * @see Rute::lesData() */ void Bane::lesData() { antVogner = lesInt("Antall vogner på banen", MINVOGNER, MAXVOGNER); lengde = lesInt("Lengde på banesettet (meter)", MINLENGDE, MAXLENGDE); - Rute::lesData(); + Rute::lesData(); // Ruten leser egne data } /** - * skrivData + * Skriver ut all informasjon om en bane til bruker i run-time (virtuell) + * + * @see Rute::skrivBeskrivelse() */ -void Bane::skrivData() const { - cout << "(bane): "; - Rute::skrivData(); +void Bane::skrivBeskrivelse() { + cout << "Banen har " << antVogner << " vogner og banesettet er " + << lengde << " meter langt.\n"; + Rute::skrivBeskrivelse(); // Rute skriver egne datamedlemmer } + /** - * skrivTilFil(...) + * Skriver ut rutetype (bane) til bruker (virtuell) + * + * @see Rute::skrivData() */ -void Bane::skrivTilFil(ofstream & ut) { - ut << "A\n"; - Rute::skrivTilFil(ut); - ut << antVogner << ' ' << lengde << '\n'; +void Bane::skrivData() const { + cout << "(bane): "; + Rute::skrivData(); // Rute skriver egne datamedlemmer } /** - * skrivBeskrivelse() + * Skriver ut alle datamedlemmer for en bane til fil (virtuell) + * + * @param ut - Filen det skrives til + * @see Rute::skrivTilFil(...) */ -void Bane::skrivBeskrivelse() { - cout << "Banen har " << antVogner << " vogner og banesettet er " - << lengde << " meter langt.\n"; - Rute::skrivBeskrivelse(); +void Bane::skrivTilFil(ofstream & ut) { + ut << "A\n"; // Skriver ut A for rutetype Bane + Rute::skrivTilFil(ut); // Rute skriver egne data + ut << antVogner << ' ' << lengde << '\n'; // Skriver egne data } \ No newline at end of file diff --git a/bane.h b/bane.h index 429d080929f2380a01e317ea6cf2d13a308c42f9..58924d39fc7cfc4046c0af31b8ceb279a4406c63 100644 --- a/bane.h +++ b/bane.h @@ -21,10 +21,9 @@ class Bane : public Rute { Bane(); Bane(std::ifstream & inn); virtual void lesData(); + virtual void skrivBeskrivelse(); virtual void skrivData() const; virtual void skrivTilFil(std::ofstream & ut); - virtual void skrivBeskrivelse(); - }; #endif \ No newline at end of file diff --git a/buss.cpp b/buss.cpp index 0919cb34051fcc3aa93c105361735fbdc11d8efd..5e9ec152cf4bdadcd41d149637aff90b3f96cdf7 100644 --- a/buss.cpp +++ b/buss.cpp @@ -12,65 +12,82 @@ using namespace std; /** - * Buss() Nullstiller alle datamedlemmer, blir lest inn reelle verdier i lesData + * Oppretter en ny Buss, nullstiller alle dens datamedlemmer. + * Faktiske reelle verdier knyttet til bussen, leses inn i lesData + * + * @see Rute::Rute() */ Buss::Buss() { antSitt = antStaa = 0; leddbuss = false; } -// TODO: Fyll inn mer her etter som header-fila tar form +/** + * Leser inn en buss sine datamedlemmer fra fil + * + * @param inn Filen det leses fra + * @see Rute::Rute(...) + */ Buss::Buss(ifstream & inn) : Rute(inn) { + // Leser alle datamedlemmene, forkaster '\n': inn >> antSitt >> antStaa >> leddbuss; inn.ignore(); } /** - * lesData() + * Leser inn alle datamedlemmer for en aktuell buss (virtuell) + * + * @see Rute::lesData() */ void Buss::lesData() { - char bussType; - + char bussType; // Hjelpevariabel for å lese om leddbuss eller ei + // Leser inn datamedlemmene: antSitt = lesInt("Antall sitteplasser på bussen", MINSITT, MAXSITT); antStaa = lesInt("Antall ståplasser på bussen", MINSTAA, MAXSTAA); bussType = lesChar("Leddbuss? (J/N)"); - while (bussType != 'J' && bussType != 'N') { + while (bussType != 'J' && bussType != 'N') { // Looper ved ulovlig svar: cout << "\nUlovlig valg, prøv igjen.\n"; bussType = lesChar("Leddbuss? J eller N"); } - if (bussType == 'J') { + if (bussType == 'J') { // Oppdaterer om faktisk leddbuss eller ei: leddbuss = true; } else if (bussType == 'N') leddbuss = false; - Rute::lesData(); + Rute::lesData(); // Rute leser resterende data } /** - * skrivData + * Skriver ut all informasjon om en buss til bruker (virtuell) + * + * @see Rute::skrivBeskrivelse() */ -void Buss::skrivData() const { - cout << "(buss): "; - Rute::skrivData(); +void Buss::skrivBeskrivelse() { + cout << "Bussen har " << antSitt << " sitteplasser, " << antStaa + << " ståplasser og er " << (leddbuss ? "" : "ikke") + << " en leddbuss.\n"; + Rute::skrivBeskrivelse(); // Rute skriver egen informasjon } /** - * skrivtilfil(...) - * @param ut + * Skriver ut egen rutetype (buss) til bruker (virtuell) + * + * @see Rute::skrivData() */ -void Buss::skrivTilFil(ofstream & ut) { - ut << "U\n"; - Rute::skrivTilFil(ut); - ut << antSitt << ' ' << antStaa - << ' ' << leddbuss << '\n'; +void Buss::skrivData() const { + cout << "(buss): "; + Rute::skrivData(); } /** - * skrivBeskrivelse() + * Skriver ut bussens datamedlemmer til fil (virtuell) + * + * @param ut Filen det skrives til + * @see Rute::skrivTilFil(...) */ -void Buss::skrivBeskrivelse() { - cout << "Bussen har " << antSitt << " sitteplasser, " << antStaa - << " ståplasser og er " << (leddbuss ? "" : "ikke") - << " en leddbuss.\n"; - Rute::skrivBeskrivelse(); +void Buss::skrivTilFil(ofstream & ut) { + ut << "U\n"; // Skriver ut rutetype, U for Buss + Rute::skrivTilFil(ut); // Rute skriver egne datamedlemmer + ut << antSitt << ' ' << antStaa // Skriver egne datamedlemmer + << ' ' << leddbuss << '\n'; // Leddbuss (1), ikke leddbuss (0) } \ No newline at end of file diff --git a/buss.h b/buss.h index de06fa478580bd2c20c7608aabf0e7829e34d404..1c5309964735adbf13546fb52b2df35adabcf2a9 100644 --- a/buss.h +++ b/buss.h @@ -23,10 +23,9 @@ class Buss : public Rute { Buss(); Buss(std::ifstream & inn); virtual void lesData(); + virtual void skrivBeskrivelse(); virtual void skrivData() const; virtual void skrivTilFil(std::ofstream & ut); - virtual void skrivBeskrivelse(); - }; #endif \ No newline at end of file diff --git a/const.h b/const.h index b53e65419f366119463f784f3c76efb68e264e69..fb61d7f96a7ffe642dc2382bebd5b2e7520c402d 100644 --- a/const.h +++ b/const.h @@ -8,16 +8,15 @@ #ifndef __CONST_H #define __CONST_H -const int MINRUTER = 1; -const int MAXRUTER = 999; -const int MINVOGNER = 2; -const int MAXVOGNER = 10; -const int MINLENGDE = 15; -const int MAXLENGDE = 150; -const int MINSITT = 20; -const int MAXSITT = 80; -const int MINSTAA = 10; -const int MAXSTAA = 40; -// TODO: INNHOLD HER +const int MINRUTER = 1; ///< Minste lovlige rutenummer +const int MAXRUTER = 999; ///< Største lovlige rutenummer +const int MINVOGNER = 2; ///< Minimum antall vogner på en bane +const int MAXVOGNER = 10; ///< Maksimum antall vogner på en bane +const int MINLENGDE = 30; ///< Minimum lengde i meter på et banesett +const int MAXLENGDE = 150; ///< Maksimum lengde i meter på et banesett +const int MINSITT = 20; ///< Minimum antall sitteplasser på en buss +const int MAXSITT = 80; ///< Maksimum antall sitteplasser på en buss +const int MINSTAA = 10; ///< Minimum antall ståplasser på en buss +const int MAXSTAA = 40; ///< Maksimum antall ståplasser på en buss #endif diff --git a/enum.h b/enum.h index a2b1b0ea85cfff1504ea58b8a05125dbb9df6483..ad091846746bfc2b186887d3e01a0eb6c2f6e3ab 100644 --- a/enum.h +++ b/enum.h @@ -8,7 +8,9 @@ #ifndef __ENUM_H #define __ENUM_H -// TODO: INNHOLD HER +/** + * Retning (hvilken vei rute skal skrives ut: Fram eller Tilbake) + */ enum Retning { Fram, Tilbake }; #endif \ No newline at end of file diff --git a/stoppested.cpp b/stoppested.cpp index 620fe6a97c9f2ce36b6c9ae9c6842bf637709c53..8f36ae473630acae8b3d24dfe8877a11770ce65b 100644 --- a/stoppested.cpp +++ b/stoppested.cpp @@ -9,12 +9,12 @@ #include <string> #include <fstream> #include <vector> -#include <algorithm> +#include <algorithm> // find, distance #include "stoppested.h" #include "stoppesteder.h" using namespace std; -extern Stoppesteder gStoppestederBase; +extern Stoppesteder gStoppestederBase; // Henter inn globalt Stopperstederobjekt /** * Run-time constructor, ifm. menyvalg S N. @@ -28,116 +28,136 @@ Stoppested::Stoppested(const string nvn) { } /** - * Constructor for å lese data dra fil - * - * @param - samme som index for å vite hva som leses inn + * Constructor fra fil + * Setter et stoppesteds navn, leser antall naboer + * og legger til eventuelle naboer og deres tid inn i datastrukturen + * + * @param nvn Stoppestedets navn (første post) + * @param inn Filen det leses fra */ -Stoppested::Stoppested(std::string nvn, ifstream & inn) { +Stoppested::Stoppested(const std::string nvn, ifstream & inn) { int antNaboer, naboNr, tidTilN; - navn = nvn; - inn >> antNaboer; inn.ignore(); - for (int i = 0; i < antNaboer; i++) { - inn >> naboNr >> tidTilN; - nabostopper.push_back(naboNr); - tidtilnabo.push_back(tidTilN); + navn = nvn; // Setter stoppestedets navn + inn >> antNaboer; inn.ignore(); // Leser et stoppesteds antall naboer + for (int i = 0; i < antNaboer; i++) { // For hver nabo + inn >> naboNr >> tidTilN; // Leser deres unike nummer og tid til + nabostopper.push_back(naboNr); // Nr legges bakerst i vektor + tidtilnabo.push_back(tidTilN); // Tid legges bakerst i vektor } - if (antNaboer != 0) // Må ha denne, ellers kutter første tegnet i navnet - inn.ignore(); -} -/** - * Returnerer et Stoppesteds unike navn - * - * @return Stoppestedets navn - */ -string Stoppested::hentStoppestedNavn() { - return navn; + if (antNaboer != 0) // Må ha denne, ellers kutter første tegnet i navnet + inn.ignore(); // Forkaster enter hvis det finnes naboer } -// TODO: Fyll på her etterhvert som header-fila tar form /** - * Skriver ut Stoppestedets navn på skjerm ifm. S A + * Sjekker om et Stoppested har en gitt nabo + * + * @param nr Evt. nabos unike nummer + * @return true Om stoppestedet har denne som nabo + * @return false Om stoppestedet ikke har denne som nabo */ -void Stoppested::skrivData() { - cout << setw(20) << navn; +bool Stoppested::finnesNabo(const int nr) { + // Prøver å finne evt. nabo: + auto it = find(nabostopper.begin(), nabostopper.end(), nr); + if (it != nabostopper.end()) { // Hvis nabostoppen finnes i vector: + return true; // Returnerer at nabo er funnet + } // Hvis ingen funn: + return false; // Returnerer at nabo ikke er funnet } /** - * skrivTilFil(...) + * Henter en nabos faktiske indeks i egen vector + * + * @param nr Naboens unike nummer som skal finnes + * @return int Avstand mellom start på vector og faktisk funn av nabo + * som = deres indeks i vectoren. + * -1 Skal ikke skje, men returner -1 hvis ikke funn */ -void Stoppested::skrivTilFil(ofstream & ut) { - ut << navn << '\n'; - ut << nabostopper.size() << '\n'; - for (int i = 0; i < nabostopper.size(); i++) { - ut << nabostopper[i] << ' '; - ut << tidtilnabo[i] << '\n'; +int Stoppested::hentNaboIndeks(const int nr) { + // Går gjennom hele vectoren, forsøker å finne et stoppesteds nummer + auto it = find(nabostopper.begin(), nabostopper.end(), nr); + if (it != nabostopper.end()) { // Funn, returnerer indeks til nummeret: + return distance(nabostopper.begin(), it); } + return -1; // Skal ikke skje } /** - * skrivNaboerOgTid() + * Henter tid mellom eget stoppested og en nabo + * + * @param nr - Naboens indeks i egen datastruktur + * @return Faktiske tid mellom eget stoppested og nabo */ -void Stoppested::skrivNaboerOgTid() { - string nvn; - - if (nabostopper.size() > 0) { - for (int i = 0; i < nabostopper.size(); i++) { - cout << setw(25) - << gStoppestederBase.hentNavnVhaIndeks(nabostopper[i]) - << " (" << setw(3) << tidtilnabo[i] - << " min mellom)\n"; - } - } else - cout << "Dette stoppestedet har ingen nabostopp.\n\n"; - +int Stoppested::hentNaboTid(const int nr) { + return tidtilnabo[nr]; } /** - * finnesNabo(...) + * Returnerer et Stoppesteds unike navn + * + * @return Stoppestedets navn */ -bool Stoppested::finnesNabo(const int nr) { - auto it = find(nabostopper.begin(), nabostopper.end(), nr); - if (it != nabostopper.end()) { // Hvis nabostoppen finnes i vector: - return true; - } // Hvis ingen funn: - return false; +string Stoppested::hentStoppestedNavn() { + return navn; } /** - * settNaboIndeks(...) + * Setter et nabostoppestedets unike nr inn i egen vector + * + * @param nr Naboens indeks */ void Stoppested::settNaboIndeks(const int nr) { - nabostopper.push_back(nr+1); + nabostopper.push_back(nr+1); // +1 her for faktiske stoppestedNr } /** - * settNaboTid(...) + * Setter tid mellom et stoppested og en nabo i egen vector + * + * @param nr Tid mellom et stoppested og en nabo */ void Stoppested::settNaboTid(const int nr) { - tidtilnabo.push_back(nr); + tidtilnabo.push_back(nr); // Legges bakerst i egen vector } /** - * hentNaboIndeks(...) + * Skriver ut Stoppestedets navn på skjerm ifm. S A + * Formaterer utskrift til å skrive navn på 20 "plasser" */ -int Stoppested::hentNaboIndeks(const int nr) { - auto it = find(nabostopper.begin(), nabostopper.end(), nr); - if (it != nabostopper.end()) { - return distance(nabostopper.begin(), it); - } - return -1; +void Stoppested::skrivData() { + cout << setw(20) << navn; } /** - * hentNaboTid(...) + * Skriver ut et stoppesteds naboer og tid til nabostoppestedene + * + * @see Stoppesteder::hentNavnVhaIndeks(...) */ -int Stoppested::hentNaboTid(const int nr) { - return tidtilnabo[nr]; +void Stoppested::skrivNaboerOgTid() { + if (nabostopper.size() > 0) { // Hvis stoppestedet har naboer: + for (int i = 0; i < nabostopper.size(); i++) { // For hver nabo: + cout << setw(25) // Skriver ut naboens navn + << gStoppestederBase.hentNavnVhaIndeks(nabostopper[i]) + << " (" << setw(3) << tidtilnabo[i] + << " min mellom)\n"; // Skriver ut tid mellom nabo og stopp + } + } else // Hvis stoppestedet ikke har naboer: + cout << "Dette stoppestedet har ingen nabostopp.\n\n"; + } -/*void Stoppested::alleNaboer(const int nr){ - for(int i=0; i < nabostopper.size(); i++) -}*/ +/** + * Skriver et stoppesteds datastruktur til fil + * + * @param ut Filen det skrives til + */ +void Stoppested::skrivTilFil(ofstream & ut) { + ut << navn << '\n'; // Skriver ut navn og antall naboer: + ut << nabostopper.size() << '\n'; + for (int i = 0; i < nabostopper.size(); i++) { // For hver nabo: + ut << nabostopper[i] << ' '; // Skriver deres unike nr + ut << tidtilnabo[i] << '\n'; // og tid mellom + } +} \ No newline at end of file diff --git a/stoppested.h b/stoppested.h index 242d1cedf536d810a591611b5a35d8efbad03d6a..360b0cd127d7e47055f91d8305e4e435285c3fb5 100644 --- a/stoppested.h +++ b/stoppested.h @@ -22,20 +22,17 @@ class Stoppested { std::vector <int> tidtilnabo; public: - Stoppested(); - Stoppested(std::string nvn, std::ifstream & inn); Stoppested(const std::string nvn); + Stoppested(const std::string nvn, std::ifstream & inn); + bool finnesNabo(const int nr); + int hentNaboIndeks(const int nr); + int hentNaboTid(const int nr); std::string hentStoppestedNavn(); + void settNaboIndeks(const int nr); + void settNaboTid(const int nr); void skrivData(); - void lesData(); void skrivNaboerOgTid(); void skrivTilFil(std::ofstream & ut); - bool finnesNabo(const int nr); - void settNaboIndeks(const int nr); - void settNaboTid(const int nr); - int hentNaboIndeks(const int nr); - int hentNaboTid(const int nr); - void alleNaboer(const int nr); }; #endif \ No newline at end of file diff --git a/stoppesteder.cpp b/stoppesteder.cpp index 9e4017e9491fcfe50dc31b1b8bef2b246231805c..f919e9bab986013d67e81a2ea3bde5936066c70d 100644 --- a/stoppesteder.cpp +++ b/stoppesteder.cpp @@ -9,34 +9,164 @@ #include <string> #include <vector> #include <fstream> -#include <algorithm> +#include <algorithm> // transform #include "LesData3.h" #include "stoppested.h" #include "stoppesteder.h" using namespace std; +/** + * Sjekker om en stoppesteds indeks finnes i vektoren + * + * @param nr - nr fra brukeren. + * @return true - Hvis indeks finnes i vektoren + * @return false - Hvis indeksen ikke finnes i vektoren + */ +bool Stoppesteder::finnesIndeks(const int nr){ + // Sjekker om medsendt nr ikke er større enn vektorens størrelse: + if (nr <= stopper.size()) { + for (int i = 0; i < stopper.size(); i++){ // For hver stoppested: + if (i == nr) //hopper ut hvis tall er funnet + return true; // Funn + } + } + return false; // Ingen funn +} + +/** + * Sjekker om Stoppesteder sin vektor er tom eller ei + * + * @return true Hvis vektor er tom + * @return false Hvis vektor ikke er tom + */ +bool Stoppesteder::tom() { + return stopper.empty(); +} + +/** + * Prøver å finne et stoppesteds navn vha dens indeks i vektoren + * + * @param nvn - Navn som skal sjekkes om finnes + * @return i - Stoppestedets faktiske indeks ved funn + * @return -1 - Har ikke funnet stoppestedets indeks (skal ikke skje) + * @see Stoppested::hentStoppestedNavn() + */ +int Stoppesteder::hentIndeksVhaNavn(const string nvn) { + string navn; // Hjelpevariabel for å sammenligne navn + for (int i = 0; i < stopper.size(); i++) { // For hvert stoppested: + navn = stopper[i]->hentStoppestedNavn(); // Henter faktisk navn + if(navn == nvn) { // Sammenligner faktisk navn med medsendt navn + return i; // Funn, returnerer indeks + } + } + return -1; // Ingen funn, skal ikke skje +} + +/** + * En funksjon som erstatter eventuelle æøåÆØÅ med eoaEOA i medsendt navn + * + * @param nvn - Et stoppesteds navn som skal få æøåÆØÅ byttet ut + * @return string - En string uten æøåÆØÅ + */ +string Stoppesteder::byttBokstaver(const string nvn) { + string nyString; // Hjelpevariabel + + for (int i = 0; i < nvn.size(); i++) { // For hver bokstav i navnet: + switch(int(nvn[i])) { // Caster om til intverdi: + case -111: nyString += 'e'; break; // -111: æ, gjør om til e + case 111: nyString += 'o'; break; // 111: ø, gjør om til o + case -122: nyString += 'a'; break; // -122: å, gjør om til a + case -110: nyString += 'E'; break; // -110: Æ, gjør om til E + case 79: nyString += 'O'; break; // 79: Ø, gjør om til O + case -113: nyString += 'A'; break; // -113: Å, gjør om til A + default: nyString += nvn[i]; // Ingen av bokstavene over, beholder + } // samme bokstav som opprinnelig + } + return nyString; // Returnerer string uten æøåÆØÅ +} + +/** + * Forsøker å finne et entydig stoppestedsnavn i datastrukturen + * + * @param nvn - Input fra bruker som skal sjekkes om matcher med et entydig + stoppesteds navn i datastrukturen + * @return string - Et stoppesteds faktiske navn ved entydighet, evt. en tom + * string hvis ikke entydig match funnet + * @see Stoppested::hentStoppestedNavn() + */ +string Stoppesteder::finnEntydig(string nvn) { + string stortNavn, // Hjelpevariabler for å sjekke om navnematch + tom; // Brukes for return av en tom string ved ikke funn + int entydig = 0; // Hjelpevariabel for å returnere evt. korrekt navn + vector <int> navneMatch; // En hjelpevektor for å mellomlagre eventuelle + // indekser som matcher med medsendt navn + + // Gjør om medsendt navn til store bokstaver: + transform(nvn.begin(), nvn.end(), nvn.begin(), ::toupper); + + for (int i = 0; i < stopper.size(); i++) { // For hvert stoppested: + stortNavn = stopper[i]->hentStoppestedNavn(); // Henter dets navn + transform(stortNavn.begin(), stortNavn.end(), // Gjør om til store + stortNavn.begin(), ::toupper); // bokstaver + + if (stortNavn.compare(nvn) == 0) { // Hele navnet matcher + navneMatch.push_back(i); // Legges indeks bakerst i hjelpevektor + entydig = navneMatch[navneMatch.size()-1]; // Henter riktig indeks + // Returnerer det faktiske navnet på stoppestedet vha. indeks: + return stopper[entydig]->hentStoppestedNavn(); + } + // Hvis deler av navnet matcher, men ikke full match: + if (stortNavn.compare(0, nvn.size(), nvn) == 0) { + navneMatch.push_back(i); // Legger indeks bakerst i hjelpevektor + } + + if (navneMatch.size() > 1) // Hvis mer enn en navnematch funnet: + return tom; // Early return, navn er ikke entydig + } + + if (navneMatch.size() == 1) { // Hvis kun en delmatch på navn: + entydig = navneMatch[0]; // Henter korrekt indeks + return stopper[entydig]->hentStoppestedNavn();// Returnerer faktisk navn + } else // Ingen registrerte navn som matcher + return tom; // Returnerer en tom string +} + +/** + * Henter et stoppesteds navn ved hjelp av dens indeks i vektoren + * + * @param nr - Stoppestedets faktiske nummer + * @return string - Stoppestedets faktiske navn + * @see Stoppested::hentStoppestedNavn() + */ +string Stoppesteder::hentNavnVhaIndeks(const int nr) { + string navn; // Hjelpevariabel for å returnere faktiske navn + // Henter stoppestedets faktiske navn vha. indeks (stoppestedets nr - 1) + navn = stopper.at(nr-1)->hentStoppestedNavn(); + return navn; // Returnerer stoppestedets faktiske navn +} /** * Forsøker å finne om et Stoppestedsnavn er duplikat * - * @param nvn - Bruker innlest navn som skal sjekkes mot faktiske Stoppestedsnavn + * @param nvn - Bruker innlest navn som skal sjekkes mot reelle Stoppestedsnavn * @return Hvis duplikat, returneres en peker til Stoppestedet med navnet * @return Hvis ikke duplikat, eller ingen stoppesteder i datastrukturen * returneres nullptr * @see Stoppested::hentStoppestedNavn() */ Stoppested* Stoppesteder::finnDuplikat(string nvn) { - string sNavn; + string sNavn; // Hjelpevariabel for å hente faktiske stoppestedets navn + // Gjør om medsent navn til store bokstaver: transform(nvn.begin(), nvn.end(), nvn.begin(), ::toupper); - if (!stopper.empty()) { // Så lenge stoppesteder er registrert: + if (!stopper.empty()) { // Hvis stoppesteder er registrert: for (int i = 0; i < stopper.size(); i++) { // For hvert stoppested: - // Bruker hjelpefunksjon for å sammenligne parameter - // og faktisk stoppestedsnavn: + // Henter faktisk navn på stoppested: sNavn = stopper[i]->hentStoppestedNavn(); + // Gjør om faktisk navn til store bokstaver: transform(sNavn.begin(), sNavn.end(), sNavn.begin(), ::toupper); - if (sNavn == nvn) - return stopper[i]; // Funn + if (sNavn == nvn) // Hvis medsendt matcher med faktisk navn + return stopper[i]; // Funn, returner peker til stoppestedet } } return nullptr; // Ingen stoppesteder i datastrukturen, eller @@ -55,58 +185,64 @@ void Stoppesteder::handling() { char valg; skrivMeny(); // Skriver ut menyvalgene til bruker - valg = lesChar("\nKommando"); + valg = lesChar("\nKommando"); // Leser brukervalg switch (valg) { case 'N': nyStop(); break; // Legge til nytt stoppested case 'A': skrivAlle(); break; // Skriv alle stoppesteder case 'E': skrivStopp(); break; // Skriv alt om et stoppested + // Går tilbake til hovedmeny: default: cout << "\nUlovlig kommando!\n"; break; } } - /** - * Leser inn informasjon om stoppesteder fra fil + * Leser inn data om stoppesteder fra fil + * + * @see Stoppested::Stoppested(...) */ void Stoppesteder::lesFraFil() { - ifstream innfilS("Stoppesteder.dta"); - string navn; + ifstream innfilS("Stoppesteder.dta"); // Åpner aktuell fil + string navn; // Hjelpevariable for å lese navn og antall stoppesteder på fil: int antStopp; - if (innfilS) { - innfilS >> antStopp; innfilS.ignore(); + if (innfilS) { // Hvis filen funnet + innfilS >> antStopp; innfilS.ignore(); // Leser antall stopp, kaster '\n' cout << "Leser " << antStopp << " stoppesteder fra 'stoppested.dta'...\n"; - getline(innfilS, navn); - while (!innfilS.eof()) { + getline(innfilS, navn); // Forsøker å lese første post + while (!innfilS.eof()) { // Så lenge ikke slutt på fil: + // Oppretter nytt stoppested og legges bakerst i vector: stopper.push_back(new Stoppested(navn, innfilS)); - getline(innfilS, navn); + getline(innfilS, navn); // Forsøker å lese neste post: } - innfilS.close(); - } + innfilS.close(); // Lukker aktuell fil + } else // Feilmelding, filen finnes ikke: + cout << "\nFant ikke filen 'stoppested.dta'...\n\n"; } /** * Legger til et nytt stoppested i datastrukturen, hvis mulig (ingen duplikat) * + * @see Stoppesteder::byttBokstaver(...) * @see Stoppesteder::finnDuplikat(...) * @see Stoppested::Stoppested(...) */ void Stoppesteder::nyStop() { Stoppested* nyStopp = nullptr; string navn; - - cout << "\nNavn på stoppested: "; getline(cin,navn); // TODO: Kanskje lage en while her, som sørger for at navn er >0 tegn - while (navn.size() < 2) { + // TODO: Lag en funksjon som sørger for at et stoppesteds navn ikke + // TODO: kun kan være tall! + cout << "\nNavn på stoppested: "; getline(cin,navn); // Leser navn + while (navn.size() < 2) { // Looper hvis navn er >2 tegn cout << "\nNavn må være 2 tegn eller mer. Prøv igjen: "; getline(cin, navn); } - navn = byttBokstaver(navn); //se kommentar i Stoppesteder::byttBokstaver + navn = byttBokstaver(navn); // fjerner evt. æøåÆØÅ i navn - if (!stopper.empty()) // Sjekker kun for duplikat, hvis det finnes stoppesteder - nyStopp = finnDuplikat(navn); + if (!stopper.empty()) // Hvis det finnes stoppesteder registrert: + nyStopp = finnDuplikat(navn); // Sjekker for duplikat if (nyStopp == nullptr) { // Ingen duplikater funnet/stoppesteder registrert nyStopp = new Stoppested(navn); // Oppretter nytt stoppested @@ -129,7 +265,7 @@ void Stoppesteder::skrivAlle() { if (!stopper.empty()) { // Hvis det finnes stoppesteder registrert: cout << "\nAlle stoppestedene i datastrukturen:\n"; for (int i = 0; i < stopper.size(); i++) { // For hvert stoppested: - cout << setw(4) << i+1 << ": "; // Skriver ut nummer + cout << setw(4) << i+1 << ": "; // Skriver ut stoppestedets nummer stopper[i]->skrivData(); // Stopp skriver eget navn n++; // Teller opp indikator if (n % 3 == 0) { // Sørger for linjeskift for hver 3.stopp @@ -140,35 +276,6 @@ void Stoppesteder::skrivAlle() { cout << "\nIngen stoppesteder registrert i datastrukturen!\n"; } -/** - * skrivStopp() TODO: LEGG INN EN SJEKK OM DET FAKTISK ER REGISTRERT STOPPESTEDER - */ -void Stoppesteder::skrivStopp() { - string navn, - entydigNavn; - Stoppested* stoppestedet = nullptr; - - if (!stopper.empty()) { - cout << "\nAlt om stoppestedet: "; getline(cin, navn); - - while (navn.size() < 2) { - cout << "\nNavn må være 2 tegn eller mer. Prøv igjen: "; - getline(cin, navn); - } - - entydigNavn = finnEntydig(navn); - - if (entydigNavn.size() > 0) { // Hvis det faktisk er et entydig navn: - cout << '\n' << entydigNavn << " har forbindelser til:\n"; - stoppestedet = finnDuplikat(entydigNavn); - stoppestedet->skrivNaboerOgTid(); - } else - cout << "\nNavnet finnes ikke, eller er ikke entydig!\n\n"; - - } else - cout << "\nIngen stopper registrert i datastrukturen!\n"; -} - /** * Skriver stoppestedsmenyens menyvalg til brukeren */ @@ -180,113 +287,53 @@ void Stoppesteder::skrivMeny() { } /** - * Skriver informasjon om stoppesteder til fil - */ -void Stoppesteder::skrivTilFil() { - ofstream utfil("Stoppesteder.dt2"); - cout << "\nSkriver til filen stoppesteder.dt2...\n"; - utfil << stopper.size() << '\n'; - for (int i = 0; i < stopper.size(); i++) { - stopper[i]->skrivTilFil(utfil); - } - utfil.close(); -} - -/** - * hentIndeksVhaNavn(...) - */ -int Stoppesteder::hentIndeksVhaNavn(const string nvn) { - string navn; - for (int i = 0; i < stopper.size(); i++) { - navn = stopper[i]->hentStoppestedNavn(); - if(navn == nvn) { - return i; - } - } - return -1; // Skal ikke skje -} - -/** - * hentNavnVhaIndeks(...) + * Skriver ut all informasjon om et stopp (navn, naboer og tid i mellom) + * + * @see Stoppesteder::finnDuplikat(...) + * @see Stoppesteder::finnEntydig(...) + * @see Stoppested::skrivNaboerOgTid() */ -string Stoppesteder::hentNavnVhaIndeks(const int nr) { - string navn; - - navn = stopper.at(nr-1)->hentStoppestedNavn(); - return navn; -} +void Stoppesteder::skrivStopp() { + string navn, // Hjelpevariabler for å lese navn fra bruker og finne + entydigNavn; // faktisk navn i datastrukturen. + Stoppested* stoppestedet = nullptr; -/** - * finnEntydig(...) // TODO: Evt. finne en lifehack hvis man skal skille mellom Oslo og Oslo S f.eks. - */ -string Stoppesteder::finnEntydig(string nvn) { - string stortNavn, - tom; - //entydig; - int entydig = 0; - vector <int> navneMatch; - // Gjør om medsendt navn til store bokstaver: - transform(nvn.begin(), nvn.end(), nvn.begin(), ::toupper); + if (!stopper.empty()) { // Hvis det finnes stoppesteder i datastrukturen + // TODO: Lag en funksjon som sørger for at et stoppesteds navn ikke + // TODO: kun kan være tall! + cout << "\nAlt om stoppestedet: "; getline(cin, navn); - for (int i = 0; i < stopper.size(); i++) { - stortNavn = stopper[i]->hentStoppestedNavn(); - transform(stortNavn.begin(), stortNavn.end(), - stortNavn.begin(), ::toupper); - if (stortNavn.compare(nvn) == 0) { // hele navnet matcher - navneMatch.push_back(i); - entydig = navneMatch[navneMatch.size()-1]; - return stopper[entydig]->hentStoppestedNavn(); - } - - if (stortNavn.compare(0, nvn.size(), nvn) == 0) { // Matcher deler av navn - navneMatch.push_back(i); + while (navn.size() < 2) { // Sørger for at navn må ha mer enn 1 tegn + cout << "\nNavn må være 2 tegn eller mer. Prøv igjen: "; + getline(cin, navn); } - if (navneMatch.size() > 1) // Ikke entydig navn: - return tom; // Early return, hvis navn ikke er entydig - } + entydigNavn = finnEntydig(navn); // Forsøker å finne et reelt navn - if (navneMatch.size() == 1) { // Entydig navn: - entydig = navneMatch[0]; - return stopper[entydig]->hentStoppestedNavn(); - } else // Ingen registrerte navn som matcher - return tom; -} + if (entydigNavn.size() > 0) { // Hvis det faktisk er et entydig navn: + cout << '\n' << entydigNavn << " har forbindelser til:\n"; + // Henter det faktiske stoppestedets peker: + stoppestedet = finnDuplikat(entydigNavn); + stoppestedet->skrivNaboerOgTid(); // Skriver dens naboer og tid + } else // Finner ingen match på navn fra bruker: + cout << "\nNavnet finnes ikke, eller er ikke entydig!\n\n"; -string Stoppesteder::byttBokstaver(const string nvn) { - string nyString; - - for (int i = 0; i < nvn.size(); i++) { - switch(int(nvn[i])) { - case -111: nyString += 'e'; break; - case 111: nyString += 'o'; break; - case -122: nyString += 'a'; break; - case -110: nyString += 'E'; break; - case 79: nyString += 'O'; break; - case -113: nyString += 'A'; break; - default: nyString += nvn[i]; - } - } - return nyString; + } else // Ingen stoppesteder i datastrukturen: + cout << "\nIngen stopper registrert i datastrukturen!\n"; } -bool Stoppesteder::tom() { - return stopper.empty(); -} /** - * @brief Sjekker om indeks nummer finnes i vektor. - * - * @param nr - nr fra brukeren. - * @return true - hvis nr er i vektoren - * @return false -hvis nr ikke er i vektoren + * Skriver stoppestedenes data til fil + * + * @see Stoppested::skrivTilFil(...) */ -bool Stoppesteder::finnesIndeks(const int nr){ - if (nr <= stopper.size()) { - for(int i=0; i < stopper.size(); i++){ //går igjennom stopper vektoren fra med sent tall - if(i==nr) //hopper ut hvis tall er funnet - return true; - } +void Stoppesteder::skrivTilFil() { + ofstream utfil("Stoppesteder.dt2"); // Åpner fil for skriving: + cout << "\nSkriver til filen stoppesteder.dt2...\n"; + utfil << stopper.size() << '\n'; // Skriver antall stoppesteder + for (int i = 0; i < stopper.size(); i++) { // For hvert stoppested: + stopper[i]->skrivTilFil(utfil); // Stoppestedet skriver seg selv til fil } - return false; + utfil.close(); // Lukker fil ved fullført skriving } \ No newline at end of file diff --git a/stoppesteder.h b/stoppesteder.h index 80d866c9692264d4eba91bf92e02bf16a1c83094..aaa8d4c0670d933830d06e03c3630a66e7956eed 100644 --- a/stoppesteder.h +++ b/stoppesteder.h @@ -19,20 +19,20 @@ class Stoppesteder { private: std::vector <Stoppested*> stopper; public: + bool finnesIndeks(const int nr); + bool tom(); + int hentIndeksVhaNavn(const std::string nvn); + std::string byttBokstaver(const std::string nvn); + std::string finnEntydig(std::string nvn); + std::string hentNavnVhaIndeks(const int nr); Stoppested* finnDuplikat(std::string nvn); void handling(); - void nyStop(); void lesFraFil(); + void nyStop(); void skrivAlle(); void skrivMeny(); void skrivStopp(); void skrivTilFil(); - bool tom(); - int hentIndeksVhaNavn(const std::string nvn); - std::string hentNavnVhaIndeks(const int nr); - std::string finnEntydig(std::string nvn); - std::string byttBokstaver(const std::string nvn); //ingen anelse hvordan få dette til å funke - bool finnesIndeks(const int nr); }; #endif \ No newline at end of file