6 svar
689 visningar
shiela behöver inte mer hjälp
shiela 23 – Fd. Medlem
Postad: 17 aug 2020 08:53

Menyval nr 1 läses inte in

Hej!
Detta är en kod som håller reda på olika transaktioner (kvitton) mellan 6 personer som är på resa tillsammans för att göra upp om hur mycket man är skyldig varandra. I dokumentet 'text.txt' finns info om transaktionerna, dvs, datum, typ av transaktion, namn på personen som betalat, belopp, antal kompisar som ingår i transaktionen och lista av namnen på dessa personer, enligt nedan:

050615  transp  Eva     6000    5       Bosse   Kristin  Paul    Torsten Stina

050721  mat     Eva     300     2       Bosse   Kristin

050721  mat     Paul    400     2       Torsten Stina

050721  transp  Bosse   5000    3       Eva     Kristin  Paul

När jag kör denna kod så läses inte menyvalen nr 1 in. När jag väljer 0, 2, 3, 4, 5, 6 i men så läses siffran in och sparas i variabeln 'menyval'. Men när jag skriver in 1 så sparas inte valet i 'menyval'.

Kan någon hjälpa mig att hitta vad felet är? Se kod nedan.

Tack på förhand! 

 

#include <iostream>

#include <fstream>

#include <string>

#include <iomanip>

using namespace std;

 

//--------------------------------------------------------

//Globala konstanter

const int MAX_KOMPISAR = 10;

const int MAX_PERSONER = 10;

const int MAX_TRANSAKTIONER = 30;

 

//--------------------------------------------------------

//Deklaration av externa funktioner

void visaMeny();

int menyVal();

 

//--------------------------------------------------------

//Klassdeklarationer

// Lagrar en persons sammanlagda transaktionsdata

class Person

{

private:

    string namn;

    double betalat_andras;   // Hur nycket man ligger ute med för andra

    double skyldig;          // Hur mycket man är skyldig andra

 

public:

    Person();

    Person(string n, double b, double s);

    double haemta_betalat();

    double haemta_skyldig();

    string haemta_namn();

    void skrivUt();

};

 

//Håller ordning på unika personer, dvs dess namn och transaktionsdata

class PersonLista

{

private:

    int antal_pers;

    Person pers[MAX_PERSONER];

 

public:

    PersonLista();

    ~PersonLista();

    void laggTillEn(Person pny);

    void skrivUtOchFixa();

    double summaSkyldig();

    double summaBetalat();

    bool finnsPerson(string namnet);          //bool finnsPerson(const string& namn);

};

 

// Lagrar data om en viss transaktion

class Transaktion

{

private:

    string datum;

    string typ;

    string namn;

    double belopp;

    int ant_kompisar;

    string kompisar[MAX_KOMPISAR];

 

public:

    Transaktion();

    ~Transaktion();

    string haemta_namn();

    double haemta_belopp();

    int haemta_ant_kompisar();

    bool finnsKompis(string namnet);

    bool laesEnTrans(istream &is);

    void skrivEnTrans(ostream &os);

    //Div annat:

    double haemta_skyldig(string namnet);

};

 

// Lagrar data om alla transaktioner (kvitton)

class TransaktionsLista

{

private:

    Transaktion trans[MAX_TRANSAKTIONER];

    int antalTrans;

 

public:

    TransaktionsLista();

    ~TransaktionsLista();

    void laesin(istream &is);

    void skrivut(ostream &os);

    void laggTill(Transaktion &t);

    double totalkostnad();

    double liggerUteMed(string namnet);

    double aerSkyldig(string namnet);

    PersonLista FixaPersoner();

};

 

// -------------------------------------------------------

// Huvudprogram:

int main()

{

    // Deklaration av variabler

    int menyval = -1; // Menyvalet för att komma till huvudmenyn

    int antal = 0; // Antal nya transaktioner för denna körning

    string namnet; // Namnet på personen som du vill veta speciell data för, dvs se personens skuld, utlägg m.m

    

    // Skapa objekt

    Transaktion t;

    TransaktionsLista tlista;

    PersonLista perslista;

    Transaktion nya_trans[MAX_TRANSAKTIONER]; // En array för tillagda transaktioner

    

    // Skapa och öppna infilsobjekt

    ifstream infil("resa.txt");

    // Skapa och öppna utfilsobjekt

    ofstream utfil("resa.txt", ios_base::app);

    // Läsa in alla data från infil

    tlista.laesin(infil);

    // Stäng infil

    infil.close();

 

    // Om användaren väljer 0 i menyn stängs programmet, men så länge användaren ej väljer 0 ska vi....

    while(menyval != 0)

    {

        visaMeny();

        menyval = menyVal(); // Hämta menyvalet

        

        // Funktionen Switch för huvudmenyns olika alternativ

        switch(menyval)

        {

            case 0: // Avsluta och skriv in nya transaktioner på fil

                cout << "\nProgrammet avslutas. Nya transaktioner skrivs in på fil."

                     << endl;

 

                for(int i = 0; i < antal; i++)

                {

                    nya_trans[i].skrivEnTrans(utfil);

                }

                utfil.close();

                break;

                

            case 1: // Läs in en transaktion från tangentbordet

                t.laesEnTrans(cin);

                tlista.laggTill(t);

                nya_trans[antal] = t;

                antal++;

                break;

                

            case 2: // Skriv info om alla transaktioner

                cout << "\nSkriver info om alla transaktioner:" << endl;

                tlista.skrivut(cout);

                cout << endl;

                break;

                

            case 3: // Skriv ut resans totala kostnad

                cout << "\nResans totala kostnad: " << tlista.totalkostnad()

                     << " kr." << endl << endl;

                break;

                

            case 4: // Kontrollera en specifik persons skuld

                cout << "Ange namn på den person vars skuld du vill kontrollera: "; cin >> namnet;

                cout << namnet << " är skyldig: " << tlista.aerSkyldig(namnet)

                     << " kr." << endl << endl;

                break;

                

            case 5: // Kontrollera en specifik persons utlägg

                cout << "Ange namn på den person vars utlägg du vill kontrollera: "; cin >> namnet;

                cout << namnet << " ligger ute med: "

                     << tlista.liggerUteMed(namnet) << " kr." << endl << endl;

                break;

                

            case 6: // Skriv ut alla resenärer och beräkna slutresultatet

                perslista = tlista.FixaPersoner();

                cout << endl;

                perslista.skrivUtOchFixa();

                cout << endl;

                break;

        }

    }

 

    return 0;

}

 

// -------------------------------------------------------

//Definition av externa funktioner

 


void visaMeny()

{

    cout << "-----------Välj vad du vill göra i menyn nedan-----------" << endl << endl;

    cout << "0. Avsluta. Alla transaktioner sparas på fil." << endl;

    cout << "1. Läs in en transaktion från tangentbordet." << endl;

    cout << "2. Skriv ut information om alla transaktioner." << endl;

    cout << "3. Beräkna totala kostnaden." << endl;

    cout << "4. Hur mycket är en viss person skyldig?" << endl;

    cout << "5. Hur mycket ligger en viss person ute med?" << endl;

    cout << "6. Lista alla personer mm och FIXA!" << endl << endl;

}

 

 


int menyVal()       //Funktionen hanterar valet i huvudmenyn

{

    int menyval;

    

    cout << "Skriv in ett tal mellan 0-6 för att göra ditt menyval: ";

    cin >> menyval;

    

    return menyval;

}

 

// -------------------------------------------------------

//Definition av metoder i alla de fyra klasserna

 

 

 

//------------Metoder i klassen Person------------

// Konstruktor

Person::Person()

{

    namn = "";

    betalat_andras = 0.0;

    skyldig = 0.0;

}

 

// Överlagrad konstruktor

Person::Person(string n, double b, double s)

{

    namn = n;

    betalat_andras = b;

    skyldig = s;

}

 

// Selektorer

double Person::haemta_betalat()

{

    return betalat_andras;

}

 

double Person::haemta_skyldig()

{

    return skyldig;

}

 

string Person::haemta_namn()

{

    return namn;

}

 

// Skriver ut information om en en specifik persons utlägg och skulder

void Person::skrivUt()

{

    if(betalat_andras > skyldig)

    {

        cout << namn << " ligger ute med " << setiosflags(ios::fixed)

             << setprecision(0) << betalat_andras << ", är skyldig "

             << setiosflags(ios::fixed) << setprecision(0) << skyldig

             << " och ska ha " << setiosflags(ios::fixed) << setprecision(0)

             << betalat_andras - skyldig << " från potten!" << endl;

    }

    else

    {

        cout << namn << " ligger ute med " << setiosflags(ios::fixed)

             << setprecision(0) << betalat_andras << ", är skyldig "

             << setiosflags(ios::fixed) << setprecision(0) << skyldig

             << " och ska betala " << setiosflags(ios::fixed) << setprecision(0)

             << skyldig - betalat_andras << " till potten!" << endl;

    }

}

 

//------------Metoder i klassen PersonLista------------

// Konstruktor

PersonLista::PersonLista()

{

    antal_pers = 0;

}

 

// Destruktor

PersonLista::~PersonLista()

{

}

 

// Lägger till en ny person till arrayen pers[]

void PersonLista::laggTillEn(Person pny)

{

    pers[antal_pers] = pny;

    antal_pers++;

}

 

// Skriver ut info om varje personobjekt i arrayen pers[]

void PersonLista::skrivUtOchFixa()

{

    for(int i = 0; i < antal_pers; i++)

    {

        pers[i].skrivUt();

    }

}

 

// Summan av alla skulder för en specifik person beräknas

double PersonLista::summaSkyldig()

{

    double skyldig = 0.0;

    

    for(int i = 0; i < antal_pers; i++)

    {

        skyldig += pers[i].haemta_skyldig();

    }

    

    return skyldig;

}

 

// Summan av alla utlägg för en given person beräknas

double PersonLista::summaBetalat()

{

    double betalat = 0.0;

 

    for(int i = 0; i < antal_pers; i++)

    {

        betalat += pers[i].haemta_betalat();

    }

 

    return betalat;

}

 

// Kontrollerar med bool om det givna namnet finns i personarrayen

bool PersonLista::finnsPerson(string namnet)

{

    for(int i = 0; i < MAX_PERSONER; i++)

    {

        if(pers[i].haemta_namn() == namnet)

        {

            return true;

}

    }

 

    return false;

}

 

//------------Metoder i klassen Transaktion------------

// Konstruktor

Transaktion::Transaktion()

{

    datum = "";

    typ = "";

    namn = "";

    belopp = 0.0;

    ant_kompisar = 0;

 

    for(int i = 0; i < MAX_KOMPISAR; i++)

    {

        kompisar[i] = "";

    }

}

 

// Destruktor

Transaktion::~Transaktion()

{

}

 

// Selektorer

string Transaktion::haemta_namn()

{

    return namn;

}

 

double Transaktion::haemta_belopp()

{

    return belopp;

}

 

int Transaktion::haemta_ant_kompisar()

{

    return ant_kompisar;

}

 

double Transaktion::haemta_skyldig(string namnet)

{

    double skuld = 0.0;

 

    for(int i = 0; i < ant_kompisar; i++)

    {

        if(kompisar[i] == namnet)

        {

            skuld = belopp / (ant_kompisar + 1);

        }

    }

 

    return skuld;

}

 

// Returnerar true om namnet finns i arrayen kompisar

bool Transaktion::finnsKompis(string namnet)

{

    for(int i = 0; i < MAX_KOMPISAR; i++)

    {

        if(kompisar[i].find(namnet, 0) != std::string::npos)

            return true;

    }

    return false;

}

 

// Läser in en transaktion

bool Transaktion::laesEnTrans(istream &is)

{

    is >> datum >> typ >> namn >> belopp >> ant_kompisar;

    for(int i = 0; i < ant_kompisar; i++)

        is >> kompisar[i];

 

    return !is.eof();

}

 

// Skriver ut information om ett transaktionsobjekt

void Transaktion::skrivEnTrans(ostream &os)

{

    os << datum << "\t" << typ << "\t" << namn << "\t" << belopp << "\t" << ant_kompisar

        << "\t";

    for(int i = 0; i < ant_kompisar; i++)

        os << kompisar[i] << "\t";

     

    os << endl;

}

 

//------------Metoder i klassen TransaktionsLista------------

// Konstruktor

TransaktionsLista::TransaktionsLista()

{

    antalTrans = 0;

}

 

// Destruktor

TransaktionsLista::~TransaktionsLista()

{

}

 

// Använder Transaktion::laesEnTrans och TransaktionsLista::laggTill för att läsa

// in data till arrayen trans[]

void TransaktionsLista::laesin(istream &is)

{

    Transaktion t;

    

    

    while(t.laesEnTrans(is))        // Så länge det finns rader kvar att läsa i infil

    {

        laggTill(t);

    }

}

 

// Använder Transaktion::skrivEnTrans för att skriva ut info om samtliga

// transaktionsobjekt i arrayen trans[]

void TransaktionsLista::skrivut(ostream &os)

{

    for(int i = 0; i < antalTrans; i++)

    {

        trans[i].skrivEnTrans(os);

    }

}

 

// Lägger till aktuellt objekt sist i arrayen trans[]

void TransaktionsLista::laggTill(Transaktion &t)

{

    trans[antalTrans] = t;

    antalTrans++;

}

 

// Beräknar summan av resans totala kostnader

double TransaktionsLista::totalkostnad()

{

    double totalkostnad = 0;

 

    for(int i = 0; i < antalTrans; i++)

    {

        totalkostnad += trans[i].haemta_belopp();

    }

    

    return totalkostnad;

}

 

// Beräknar hur mycket en specifik person ligger ute med

double TransaktionsLista::liggerUteMed(string namnet)

{

    double betalat = 0.0;

    

    for(int i = 0; i < antalTrans; i++)

    {

        if(trans[i].haemta_namn() == namnet)

            betalat += (trans[i].haemta_belopp() - (trans[i].haemta_belopp() /

                       (trans[i].haemta_ant_kompisar() + 1)));

    }

    

    return betalat;

}

 

// Beräknar hur mycket en specifik person är skyldig att betala i potten

double TransaktionsLista::aerSkyldig(string namnet)

{

    double skyldig = 0.0;

    

    for(int i = 0; i < antalTrans; i++)

    {

        if (trans[i].finnsKompis(namnet))

            skyldig += trans[i].haemta_skyldig(namnet);

    }

    

    return skyldig ;

}

 

// Skapar ett PersonList-objekt med data om en specifik persons transaktioner

PersonLista TransaktionsLista::FixaPersoner()

{

    PersonLista perslista;

    string persnamn;

    double persskuld;

    double persbetalat;

 

    for(int i = 0; i < antalTrans; i++)

    {

        if(!perslista.finnsPerson(trans[i].haemta_namn()))

        {

            persnamn = trans[i].haemta_namn();

            persskuld =+ aerSkyldig(persnamn);

            persbetalat =+ liggerUteMed(persnamn);

 

            Person nypers = Person(persnamn, persbetalat, persskuld);

            perslista.laggTillEn(nypers);

        }

    }

    

    return perslista;

}

Laguna Online 30721
Postad: 17 aug 2020 10:05

Lägg in spårutskrifter i laesEnTrans och laggTill för att se vad koden gör. Hur ser du att det inte händer något?

shiela 23 – Fd. Medlem
Postad: 17 aug 2020 10:14
Laguna skrev:

Lägg in spårutskrifter i laesEnTrans och laggTill för att se vad koden gör. Hur ser du att det inte händer något?

Jag ser att det ej händer något eftersom när jag skriver 1 och trycker på enter så "fastnar" programmet, dvs bara väntar på mer input från användaren  istället för att vara nöjd med 1:an som svar (markören hoppar ner en rad istället för att läsa in 1:an)  

joculator 5296 – F.d. Moderator
Postad: 17 aug 2020 10:18

case 1: // Läs in en transaktion från tangentbordet
                t.laesEnTrans(cin);
                tlista.laggTill(t);
                nya_trans[antal] = t;
                antal++;
                break;

 

Är det inte det den skall göra (enligt din kod). Den väntar på en input?

shiela 23 – Fd. Medlem
Postad: 17 aug 2020 10:32
joculator skrev:

case 1: // Läs in en transaktion från tangentbordet
                t.laesEnTrans(cin);
                tlista.laggTill(t);
                nya_trans[antal] = t;
                antal++;
                break;

 

Är det inte det den skall göra (enligt din kod). Den väntar på en input?

Ja precis, men när jag skriver in en input ska det ju läsa in den och spara i variabeln 'menyval' se denna snutt:

int menyVal()       //Funktionen hanterar valet i huvudmenyn

{

    int menyval;

    cout << "Skriv in ett tal mellan 0-6 för att göra ditt menyval: ";

    cin >> menyval;

    return menyval;

}

... och det funkar fint för alla siffror utan just siffran '1'. Och jag förstår ej varför! :(

Laguna Online 30721
Postad: 17 aug 2020 10:44
shiela skrev:
Laguna skrev:

Lägg in spårutskrifter i laesEnTrans och laggTill för att se vad koden gör. Hur ser du att det inte händer något?

Jag ser att det ej händer något eftersom när jag skriver 1 och trycker på enter så "fastnar" programmet, dvs bara väntar på mer input från användaren  istället för att vara nöjd med 1:an som svar (markören hoppar ner en rad istället för att läsa in 1:an)  

Den står väl i laesEnTrans och väntar på att du ska skriva in mer. Vad tycker du borde hända? 

shiela 23 – Fd. Medlem
Postad: 17 aug 2020 14:04 Redigerad: 17 aug 2020 14:05
Laguna skrev:
shiela skrev:
Laguna skrev:

Lägg in spårutskrifter i laesEnTrans och laggTill för att se vad koden gör. Hur ser du att det inte händer något?

Jag ser att det ej händer något eftersom när jag skriver 1 och trycker på enter så "fastnar" programmet, dvs bara väntar på mer input från användaren  istället för att vara nöjd med 1:an som svar (markören hoppar ner en rad istället för att läsa in 1:an)  

Den står väl i laesEnTrans och väntar på att du ska skriva in mer. Vad tycker du borde hända? 

Tack! Jag insåg vad feler var! Det var lite klantigt av mig, insåg att jag glömt bort att man såklart måste ange inputen i ordningen is >> datum >> typ >> namn >> belopp >> ant_kompisar; enligt funktionen laesEnTrans!

 

Tack för hjälpen, din kommentar var guldvärd när man snöar in sig på något så enkelt!! :D

Svara
Close