Skip to content
Snippets Groups Projects
Select Git revision
  • cb1e7642b58411d617e22f4022e6b72c65249c53
  • master default protected
  • 69-resize-image-before-upload
  • 60-add-match-salamander-modal-to-edit-salamander
  • 50-fix-server-error-message
  • 48-fix-gradle
  • 31-camera-communicate-with-api-and-delete-from-cache-2
  • 20-changing-verification-step-in-profile-to-modal
  • 4-add-all-basic-views
  • 1-setup
10 results

AccountData.js

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    rute.cpp 22.56 KiB
    /**
     * @file rute.cpp
     * @author Andreas Blakli
     */
    
    #include "rute.h"
    
    using namespace std;
    
    extern Stoppesteder* gStoppesteder;
    
    /**
     * Constructor for Rute objekt.
     *
     */
    Rute::Rute() {
    }
    
    /**
     * Destructor for Rute objektet.
     *
     */
    Rute::~Rute() {
    }
    
    /**
     * Lager ett nytt stopp i ruten.
     *
     * @param eksisterende - Indexen til ett eksisterende stoppested.
     * @param pos - Posisjonen til iteratoren.
     * @return Stopp* - Ett nytt stopp hvis alt stoppet er lovlig nullptr ellers.
     */
    Stopp* Rute::ny(const int& eksisterende, int pos) {
        string stoppPlass = "";
        Stoppested *stoppested, *forrigeStoppested;
        Stopp *stopp, *forrigeStopp;
        stoppested = nullptr;
        stopp = nullptr;
        bool forsteStopp = true;
    
        do {
            forrigeStoppested = stoppested;
            forrigeStopp = stopp;
            if (eksisterende != -1) {
                forrigeStoppested = gStoppesteder->hentEksisterende(eksisterende);
                forrigeStopp = new Stopp;
                forrigeStopp->indexStoppested = eksisterende;
            }
            stopp = new Stopp;
            stoppested = nullptr;
            if (alleStoppestedenePaaRuten.size() > 0) forsteStopp = false;
            cout << "\nSkriv inn navn eller nummer på stoppeplass du ønsker "
                 << "å legge til (blankt for avbryt):";
            getline(cin, stoppPlass);
    
            // Strengen ikke er tom
            if (!stoppPlass.empty()) {
                stoppPlass = hjelp.rensStreng(stoppPlass);
                if (!hjelp.erBokstav(stoppPlass)) {
                    // Hvis tall
                    stoppested = gStoppesteder->hentEksisterende(stoi(stoppPlass) - 1);
                } else
                    // Else bokstav(r)
                    stoppested = gStoppesteder->hentEksisterende(stoppPlass);
    
                // Hvis stoppestedet ikke eksisterer fra før og input er bokstaver
                if (stoppested == nullptr && hjelp.erBokstav(stoppPlass)) {
                    cout << "\nError: Stoppested eksisterer ikke!" << '\n'
                         << "Oppretter nytt stoppsted basert på forrige gitte parameter."
                         << '\n';
                    if (forsteStopp)
                        gStoppesteder->ny(stoppPlass, false);
                    else
                        gStoppesteder->ny(stoppPlass, true);
                    stoppested = gStoppesteder->hentEksisterende(stoppPlass);
                }
                stopp->indexStoppested = gStoppesteder->hentIndex(stoppested);
    
                // Er ikke første stopp og har ikke nabostopp
                if (!forsteStopp && stoppested->hentTidNaboStopp() < 0) {
                    stopp->minutterFraForrigeStoppested = lesTid();
                } else if (forsteStopp)
                    stopp->minutterFraForrigeStoppested = 0;
                else {
                    stopp->minutterFraForrigeStoppested = -1;
                }
                if (!sjekkOmStoppEksisterer(stopp)) {
                    oppdaterStoppestedVectorer(stoppested,
                                               forrigeStoppested,
                                               stopp,
                                               forrigeStopp);
                    if (eksisterende != -1 && pos == alleStoppestedenePaaRuten.size()) {
                        alleStoppestedenePaaRuten.push_back(stopp);
                    } else if (eksisterende != -1) {
                        auto it = alleStoppestedenePaaRuten.begin();
                        advance(it, pos);
                        Stopp* tmpstopp = *it;
                        int tmpTid = tmpstopp->minutterFraForrigeStoppested;
                        tmpstopp->minutterFraForrigeStoppested = stopp->minutterFraForrigeStoppested;
                        stopp->minutterFraForrigeStoppested = tmpTid;
                        alleStoppestedenePaaRuten.insert(it, stopp);
                        pos++;
                    } else
                        alleStoppestedenePaaRuten.push_back(stopp);
                    cout << "\nStopp lagt til!" << '\n';
                } else
                    cout << "\nError: Stopp er allerede lagt til!" << '\n';
            }
        } while (!stoppPlass.empty());
    
        // Hvis ikke nok stopp er lagt inn på ruten
        if (alleStoppestedenePaaRuten.size() <= 1 && eksisterende == -1) {
            cout << "\nIkke nok stopp lagt inn! Avbryter" << '\n';
            return nullptr;
        }
        return stopp;
    }
    
    /**
     * Sletter alle pekerne i listen over alle stoppestedene i ruten.
     *
     */
    void Rute::ryddOppMinne() {
        for (const auto& val : alleStoppestedenePaaRuten) {
            delete val;
        }
        alleStoppestedenePaaRuten.clear();
    }
    
    /**
     * Sjekker om et stopp eksiterer fra før i  listen over alle
     * stoppestedene i ruten.
     *
     * @param stopp - Peker til stoppet.
     * @return true - Hvis stoppet eksisterer i ruten.
     * @return false - Hvis stoppet ikke eksisterer i ruten.
     */
    bool Rute::sjekkOmStoppEksisterer(Stopp* stopp) {
        for (const auto& val : alleStoppestedenePaaRuten) {
            if (val->indexStoppested == stopp->indexStoppested) return true;
        }
        return false;
    }
    
    /**
     * Skriver ut informasjon om ruten forlengs og baklengs.
     *
     * @see skrivDataForlengs().
     * @see skrivDataBaklengs().
     */
    void Rute::skrivData() {
        skrivDataForlengs();
        skrivDataBaklengs();
    }
    
    /**
     * Skriver ut informasjon om ruten forlengs. Fra startstopp til
     * endestopp til terminal.
     *
     * @see Stoppested::hentEksisterende().
     * @see Stoppested::hentNavn().
     */
    void Rute::skrivDataForlengs() {
        Stoppested* stopp;
        int totalTid, storrelseListe;
        totalTid = 0;
        storrelseListe = alleStoppestedenePaaRuten.size();
        cout << "\n\n\t..::Stoppested navn\tTid mellom stopp"
             << "\tTotal tid fra rutestart::..";
        for (const auto& val : alleStoppestedenePaaRuten) {
            if (val->minutterFraForrigeStoppested != 0)
                totalTid += val->minutterFraForrigeStoppested;
            stopp = gStoppesteder->hentEksisterende(val->indexStoppested);
            if (stopp != nullptr) {
                cout << "\n\t\t"
                     << stopp->hentNavn()
                     << setw(15)
                     << "\t" << val->minutterFraForrigeStoppested
                     << setw(15)
                     << "\t\t" << totalTid
                     << setw(15);
            }
        }
    }
    
    /**
     * Skriver ut informasjon om ruten baklengs, dvs
     * fra endestopp til startstopp til terminal.
     *
     * @see Stoppested::hentEksisterende().
     * @see Stoppested::hentNavn().
     */
    void Rute::skrivDataBaklengs() {
        Stoppested* stoppested;
        Stopp *stopp, *forrigeStopp;
        int totalTid, storrelseListe;
        bool forste = true;
    
        totalTid = 0;
        cout << "\n\n\t..::Stoppested navn\tTid mellom stopp"
             << "\tTotal tid fra rutestart::..";
    
        for (auto it = alleStoppestedenePaaRuten.rbegin();
             it != alleStoppestedenePaaRuten.rend(); it++) {
            stopp = *it;
            stoppested = gStoppesteder->hentEksisterende(stopp->indexStoppested);
            if (!forste) {
                totalTid += forrigeStopp->minutterFraForrigeStoppested;
                cout << "\n\t\t"
                     << stoppested->hentNavn()
                     << setw(15)
                     << "\t" << forrigeStopp->minutterFraForrigeStoppested
                     << setw(15)
                     << "\t\t" << totalTid
                     << setw(15);
            } else {
                cout << "\n\t\t"
                     << stoppested->hentNavn()
                     << setw(15)
                     << "\t" << 0
                     << setw(15)
                     << "\t\t" << 0
                     << setw(15);
                forste = false;
            }
            forrigeStopp = *it;
        }
    }
    
    /**
     * Funksjonen styrer om stopp skal slettes eller endres
     * i en eksisterende rute.
     *
     * @see lesData3 lesInt().
     * @see slettStoppested().
     * @see smettInnStoppested().
     */
    void Rute::endre() {
        int valg, antall;
        cout << "\n\n1 - Slett stoppested\n2 - Smett inn stoppested\n0 - Avbryt" << '\n';
        valg = lesInt("Kommando", 0, 2);
        antall = alleStoppestedenePaaRuten.size();
        if (valg > 0) {
            int start, slutt;
            start = slutt = 0;
            start = lesInt("Hvilke stoppested utgjør start punktet?",
                           1, antall);
    
            if (valg == 1 && antall > 2 && start < antall) {
                slutt = lesInt("Hvilket stoppested utgjør slutt ytterpunkt?",
                               start + 2, antall);
                slettStoppested(start, slutt);
            } else if (valg == 2)
                slutt = lesInt("Hvilket stoppested utgjør slutt ytterpunkt?",
                               start, antall);
            else
                cout << "\nError i sletting: ugyldig input!" << '\n';
    
            if (valg == 2 && slutt - 1 == start || valg == 2 && slutt == start)
                smettInnStoppested(start, slutt);
    
            else if (valg == 2)
                cout << "\nError: For smett inn så må slutt være rett etter start "
                     << "for at innsmettingen skal være entydig!\n";  //" << '\n'
        }
    }
    
    /**
     * Sletter ett eller flere stopp fra ruten mellom
     * de angitte parameterne.
     *
     * @param start - Slett fra.
     * @param slutt - Slett til.
     */
    void Rute::slettStoppested(const int& start, const int& slutt) {
        Stopp* stopp;
        auto it = alleStoppestedenePaaRuten.begin();
        advance(it, start);
        for (int i = start; i < slutt - 1; i++) {
            stopp = *it;
            delete stopp;
            it = alleStoppestedenePaaRuten.erase(it);
        }
        skrivData();
    }
    
    /**
     * Smetter inn et stoppested mellom angitte parameter
     * verdier.
     *
     * @param start - Fra stopp.
     * @param slutt - Til stopp.
     *
     * @see ny().
     */
    void Rute::smettInnStoppested(const int& start, const int& slutt) {
        Stopp* stopp;
        list<Stopp*>::iterator it = alleStoppestedenePaaRuten.begin();
        advance(it, start - 1);
        stopp = *it;
        if (slutt == start && start < alleStoppestedenePaaRuten.size())
            ny(stopp->indexStoppested, start - 1);
        else
            ny(stopp->indexStoppested, start);
    }
    
    /**
     * Legger til ett stopp i ruten hvis det ikke er nullptr.
     *
     * @param stopp - Peker til stopp.
     */
    void Rute::leggTilStoppestedIRute(Stopp* stopp) {
        if (stopp != nullptr)
            alleStoppestedenePaaRuten.push_back(stopp);
    }
    
    void Rute::skrivType() {
    }
    
    /**
     * Oppdaterer stoppestedet og stoppestedets naboer sine indexer til naboer
     * og minutter mellom de relaterte nabo stoppene.
     *
     * @param stoppested - Peker til nåværende stoppested.
     * @param forrigeStoppested - Peker til det forrige stoppestedet.
     * @param stopp - Peker til det nåværende stoppet.
     * @param forrigeStopp - Peker til det forrige stoppet.
     *
     * @see Stoppested::hentAntallStoppestedVector().
     * @see Stoppested::hentTidNaboStopp().
     * @see Stoppested::hentTidForsteNabo().
     * @see Stoppested::leggTilNaboBakerst().
     * @see Stoppested::leggTilNaboFremst().
     * @see Stoppested::leggTilNaboStopp().
     */
    void Rute::oppdaterStoppestedVectorer(Stoppested* stoppested,
                                          Stoppested* forrigeStoppested,
                                          Stopp* stopp,
                                          Stopp* forrigeStopp) {
        int tmpTid2, tmpTid;
        tmpTid2 = tmpTid = -1;
        int antIVec = stoppested->hentAntallStoppestedVector();
        Stoppested* tmpstd = stoppested;
        if (stoppested != nullptr) {
            tmpTid = stoppested->hentTidNaboStopp();
        }
        if (forrigeStoppested != nullptr) {
            if (stopp->minutterFraForrigeStoppested == -1) {
                tmpTid2 = stoppested->hentTidForsteNabo();
                if (tmpTid2 == -1) tmpTid2 = stoppested->hentTidNaboStopp();
                // Legger nåværende stopp til i forrige stoppested
                forrigeStoppested->leggTilNaboBakerst(stopp->indexStoppested,
                                                      tmpTid2);
    
            } else
                forrigeStoppested->leggTilNaboBakerst(stopp->indexStoppested,
                                                      stopp->minutterFraForrigeStoppested);
    
            if (stoppested->hentIndex() != forrigeStopp->indexStoppested) {
                if (stopp->minutterFraForrigeStoppested == -1) {
                    // Legger til nåværende stopp til stoppested
                    stoppested->leggTilNaboFremst(forrigeStopp->indexStoppested,
                                                  tmpTid2);
                } else
                    stoppested->leggTilNaboFremst(forrigeStopp->indexStoppested,
                                                  stopp->minutterFraForrigeStoppested);
            }
        } else if (antIVec < 1) {
            stoppested->leggTilNaboStopp(-1, -1);
        }
        // Gir stopp nabo-tid slik at rute beskrivelse fungerer korrekt
        if (stopp->minutterFraForrigeStoppested == -1)
            stopp->minutterFraForrigeStoppested = stoppested->hentTidNaboStopp();
    }
    
    /**
     * Leser inn tid fra CLI.
     *
     * @return int - Brukervalgte tid.
     * @see LesData3 lesInt().
     */
    int Rute::lesTid() {
        return lesInt("Tid mellom forrige stopp i minutter",
                      MIN_MINUTTER,
                      MAX_MINUTTER);
    }
    
    /**
     * Styrer alt som har med tabell logikk å gjøre dvs.
     * Den skriver ut en tabell for et spesefikt stoppested
     * i en spesefikk rute mellom bruker valgte tidspunkt
     * enten framlengs eller baklengs.
     *
     * @see Stoppesteder::hentEksisterende().
     * @see Stoppested::hentNavn().
     * @see skrivDataForlengs().
     * @see skrivDataBaklengs().
     * @see HjelpeFunksjoner::rensStreng().
     * @see HjelpeFunksjoner::skrivKlokkeslett().
     * @see LesData3 lesInt().
     * @see HjelpeFunksjoner::lesTall().
     * @see hentTotalTidForan().
     * @see hentTotalTidTilbake().
     */
    void Rute::tabell() {
        Retning retning = Annen;
        Stoppested* stoppested;
        string stopp, stopp2, navn;
        char valg = '\0';
        bool ikkeFullt, igjen;
        ikkeFullt = igjen = true;
        vector<vector<int>> valgtTid;
        int avgangsTid, fraKlTime, fraKlMin, tilKlTime, tilKlMin,
            tmpTime, tmpMin, forrigeTmpMin, totTid, utregning;
    
        tmpTime = tmpMin = forrigeTmpMin = totTid = utregning = fraKlTime = 0;
        tilKlMin = MIN_MINUTTER;
        tilKlTime = MIN_TIMER;
        stopp = gStoppesteder->hentEksisterende(
                                 alleStoppestedenePaaRuten.front()->indexStoppested)
                    ->hentNavn();
        stopp2 = gStoppesteder->hentEksisterende(
                                  alleStoppestedenePaaRuten.back()->indexStoppested)
                     ->hentNavn();
        cout << "\nFram: Retningen: "
             << stopp
             << " - "
             << stopp2
             << "\nTilbake: Retningen: "
             << stopp2
             << " - "
             << stopp
             << '\n'
             << "\nVelg retning F = Fram, T = Tilbake"
             << '\n';
    
        while (valg != 'F' && valg != 'T') {
            valg = lesChar("Kommando: ");
            if (valg == 'F')
                retning = Fram;
            else if (valg == 'T')
                retning = Tilbake;
    
            switch (retning) {
                case Fram:
                    skrivDataForlengs();
                    break;
                case Tilbake:
                    skrivDataBaklengs();
                    break;
                default:
                    cout << "\nUgyldig valg!" << '\n';
                    break;
            }
        }
        cout << "\n\nSkriv inn navnet på stoppet: ";
        getline(cin, navn);
        navn = hjelp.rensStreng(navn);
        stoppested = gStoppesteder->hentEksisterende(navn);
        if (stoppested != nullptr) {
            cout << "\nTime= 0 og Minutt= 0 for å AVSLUTTE innlesning" << '\n';
            do {
                igjen = true;
                do {
                    cout << "\nFra kl. (";
                    hjelp.skrivKlokkeslett(tilKlTime, tilKlMin);
                    cout << " - ";
                    hjelp.skrivKlokkeslett(MAX_TIMER, MAX_MINUTTER);
                    cout << "): "
                         << "\nTime: ";
                    fraKlTime = hjelp.lesTall();
                    cout << "\nMinutt: ";
                    fraKlMin = hjelp.lesTall();
                    if (fraKlTime < MAX_TIMER &&
                        fraKlTime > tilKlTime &&
                        fraKlMin < MAX_MINUTTER &&
                        fraKlMin >= 0)
                        igjen = false;
                    if (fraKlTime <= 0 && fraKlMin <= 0)
                        igjen = false;
                } while (igjen);
    
                // Hvis ikke avslutte
                if (fraKlTime > 0 || fraKlMin > 0) {
                    avgangsTid = lesInt("Tid mellom avganger", MIN_AVGANGS_TID, MAX_AVGANGS_TID);
    
                    tmpTime = fraKlTime + (avgangsTid / 60);
                    tmpMin = fraKlMin + (avgangsTid % 60);
                    if (tmpMin > MAX_MINUTTER) {
                        tmpTime++;
                        tmpMin = tmpMin % 60;
                    }
    
                    // Hvis tid gitt går over max verdi i.e. 24t
                    if (tmpTime > MAX_TIMER)
                        ikkeFullt = false;
    
                    do {
                        cout << "\nTil kl. (";
                        hjelp.skrivKlokkeslett(tmpTime, tmpMin);
                        cout << " - ";
                        hjelp.skrivKlokkeslett(MAX_TIMER, MAX_MINUTTER);
                        cout << "): "
                             << "\nTime: ";
                        tilKlTime = hjelp.lesTall();
                        cout << "\nMinutt: ";
                        tilKlMin = hjelp.lesTall();
                    } while (tilKlTime > MAX_TIMER ||
                             tilKlTime < tmpTime ||
                             tilKlMin > MAX_MINUTTER || tilKlMin < 0);
    
                    // Legger til tider i vector
                    if (ikkeFullt) {
                        valgtTid.push_back({fraKlTime, fraKlMin, tmpTime,
                                            tmpMin, avgangsTid,
                                            tilKlTime, tilKlMin, tmpTime});
                    }
                } else {
                    fraKlTime = fraKlMin = tilKlTime = tilKlMin = 0;
                }
    
            } while (fraKlTime > 0 || fraKlMin > 0 || tilKlTime > 0 || tilKlMin > 0);  // fraKlTime != 0 || fraKlMin != 0 && tilKlTime != 0 || tilKlMin != 0 && ikkeFullt);
    
            if (retning == Fram)
                totTid = hentTotalTidForan(gStoppesteder->hentIndex(stoppested));
            else
                totTid = hentTotalTidTilbake(gStoppesteder->hentIndex(stoppested));
    
            // Har tid har blitt lagt til i vector
            if (valgtTid.size() > 0) {
                cout << "\n\t..::Rutetabell for stoppestedet: " << navn
                     << "::.."
                     << "\n\n";
                // Klokkeslett
                for (int i = valgtTid.front()[0];
                     i <= valgtTid.back()[5]; i++) {
                    if (i <= 9)
                        cout << "\t\t0" << i;
                    else
                        cout << "\t\t" << i;
                    cout << ":";
    
                    // Tabell for stopp på 'i' klokkeslett
                    int tall = 0;
                    int timeAvgang = 0;
                    int minutterAvgang = 0;
                    for (auto& val : valgtTid) {
                        if (i >= val[0] && i <= val[5]) {
                            igjen = true;
                            timeAvgang = (val[4] + totTid) / 60;
                            minutterAvgang = (val[4] + totTid) % 60;
                            if ((val[4] + totTid) % 60 != 0)
                                timeAvgang++;
    
                            if (val[7] == i)
                                tall = minutterAvgang;
                            else
                                tall = totTid + val[4];
    
                            while (igjen) {
                                // På samme time
                                if (i >= val[2]) {
                                    if (tall < MAX_MINUTTER && val[7] == i) {
                                        cout << "\t";
                                        if (tall <= 9)
                                            cout << "0" << tall;
                                        else
                                            cout << tall;
                                        if (val[4] > MAX_MINUTTER)
                                            igjen = false;
                                        tall += totTid + val[4];
    
                                    } else {
                                        igjen = false;
                                    }
                                } else
                                    igjen = false;
                            }
                            if (val[7] == i)
                                val[7] += timeAvgang;
                        }
                    }
                    cout << '\n';
                }
            }
        } else
            cout << "\nError: Fant ikke noe stoppested med det navnet!" << '\n';
    }
    
    /**
     * Henter total tid fra stoppested start til angitt parameter.
     *
     * @param pos - Indexen til stoppestedet.
     * @return int - Den totale tiden fra start stopp til pos.
     */
    int Rute::hentTotalTidForan(const int& pos) {
        int totalTid;
        totalTid = 0;
        for (const auto& val : alleStoppestedenePaaRuten) {
            if (val->minutterFraForrigeStoppested != 0)
                totalTid += val->minutterFraForrigeStoppested;
            if (val->indexStoppested == pos)
                return totalTid;
        }
        return -1;
    }
    
    /**
     * Henter total tid fra stoppested slutt til angitt parameter.
     * Brukes når man trenger total tid "reversert" som i skrivDataBaklengs().
     *
     * @param pos - Indexen til stoppestedet.
     * @return int - Den totale tiden fra slutt stopp til pos.
     */
    int Rute::hentTotalTidTilbake(const int& pos) {
        Stopp *stopp, *forrigeStopp;
        int totalTid;
        bool forste = true;
        totalTid = 0;
    
        for (auto it = alleStoppestedenePaaRuten.rbegin();
             it != alleStoppestedenePaaRuten.rend(); it++) {
            stopp = *it;
            if (!forste) {
                totalTid += forrigeStopp->minutterFraForrigeStoppested;
                if (stopp->indexStoppested == pos) return totalTid;
            } else {
                forste = false;
            }
            forrigeStopp = *it;
        }
        return -1;
    }
    
    /**
     * Leser inn stopp fra fil og lager en nye pekere til
     * Stopp structs som legges til listen over alle stoppesteder
     * på ruten.
     *
     * @param inn - Inn data fil-strøm.
     * @see HjelpeFunksjoner::splittStreng().
     */
    void Rute::lesFraFil(ifstream& inn) {
        Stopp* stopp = nullptr;
        vector<string> linjenSplittet;
        int pos = 0;
        string heleLinjen = "";
        do {
            getline(inn, heleLinjen);
            linjenSplittet = hjelp.splittStreng('*', heleLinjen);
            pos = 0;
            if (heleLinjen != "Buss" && heleLinjen != "Bane" && heleLinjen != "X") {
                for (int i = 0; i < linjenSplittet.size() - 1; i++) {
                    switch (i) {
                        case 0: {
                            stopp = new Stopp;
                            stopp->indexStoppested = stoi(linjenSplittet[0]);
                            break;
                        }
                        case 1: {
                            stopp->minutterFraForrigeStoppested = stoi(linjenSplittet[1]);
                            alleStoppestedenePaaRuten.push_back(stopp);
                            break;
                        }
                    }
                    pos++;
                }
            }
        } while (heleLinjen != "Buss" && heleLinjen != "Bane" && heleLinjen != "X");
    }
    
    /**
     * Skriver alle stopp på en rute til fil.
     *
     * @param ut - Ut data fil-strøm.
     */
    void Rute::skrivTilFil(ofstream& ut) {
        for (const auto& val : alleStoppestedenePaaRuten) {
            ut << val->indexStoppested << '*'
               << val->minutterFraForrigeStoppested << '*'
               << '\n';
        }
    }