C++ Einkaufsliste aber wie?



  • Hallo Liebe Programmier Geminde

    Ich würde gerne in C++ eine Art Shop schreiben in dem man verschiedene Waffen hat welche, einen Preis haben und einen Schaden.
    Wie kann ich dies machen?
    Den Shop möchte ich als eine Funktion haben und es soll wenn eine auswahl getroffen worden ist, diese "Speichern"

    Beispiel:

    Herzlich willkommen im Shop was möchtest du kaufen?
    1. Schwert (18 DMG, 200 Euro)
    2. Dolch (10 DMG, 100 Euro)
    3. Armbrust (14 DMG, 300 Euro)

    Wenn ich jetzt 1 eingebe soll er mir auf einen String "Schwert" schreiben, mir auf einen Integer die DMG (18) schreiben und von meinem Geldbeutel(global oder lokale variable??) 200 abziehen.

    Ich habe zwar eine Lösung gefunden, jedoch ist diese sehr, sehr ungeschickt und brauchtzu viel Platz (Sehr langer Code):

    #include <stdio.h>
    #include <tchar.h>
    #include <stdlib.h>
    #include <string>
    #include <time.h>
    #include <csetjmp>
    #include <stddef.h>
    #include <iostream>
    #include <conio.h>
    #include <dos.h>
    #include <conio.h>
    #include <Windows.h>
    
    using namespace std;
    
    int a;
    int c;
    int geldbeutel;
    
    int shop(int c)
    {
          cout<<"Bitte Waffe auswählen\n";
    		cin>>a;
    		switch(a)
    		{
    			case 1: c=1; break;
    			case 2 : c=2; break;
    			case 3 : c=3; break;
    		}
    			std::system("cls");
    			return(c);
    			break; 
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
         switch(shop(0))
         {
    	case 1: 
    	if(geldbeutel>=200)
    	{
    	        waffe="Schwert"; 
                     schaden=18;
                     geldbeutel=geldbeutel-200; 
                     break;
    	}
    	else
    	{
    		cout <<"zuweniggeld\n";
    	}
    
    	case 2: 
    	if(geldbeutel>=100)
    	{
    		waffe="Dolch";
                     schaden=10;
                     geldbeutel=geldbeutel-100; 
                     break;
    	}
    	else
    	{
    		cout <<"zuweniggeld\n";
    	}
    
    	case 3: 
    	if(geldbeutel>=300)
    	{
    		waffe="Armbrust"; 
                     schaden=14;
                     geldbeutel=geldbeutel-300; 
                     break;
    	}
    	else
    	{
    		cout <<"zuweniggeld\n";
    	}
    

    Bei so wenigen Waffen währe diese Lösung für mich in ordungn nun habe ich jedoch 100+ Waffen -.-

    Klassen habe ich mir auch angeschaut und die Variabeln auf KLassen zu schreiben wäre kein Problem jedoch habe ich immer das gleiche Problem:
    Die Auswahl welche Waffe gekauft wurde.

    Kann mir wer weiterhelfen?

    Ich verwende den Microsoft Visual Studio 2008 Compailer.

    Mit Freundlichen Grüssen

    nimda4



  • Hallo, folgendes wäre z.B. denkbar:

    Du schreibst in eine Textdatei alle Kombinationen von Waffe und Schaden und ähnlichen Informationen die du haben möchtest und trennst die Informationen mit irgendeinem Trennzeichen(etwa einem Leerzeichen oder einem Komma).
    Dann liest du in deinem Programm die Datei aus und lädst die Informationen in eine Klasse, welche du dann ganz standardmäßig ausgeben kannst.

    Also kleines Beispiel:

    Textdatei:

    Schwert 19 200
    Armbrust 10 100
    usw

    Zuerst steht der Name dort, danach der Schaden und dann die Kosten.

    Die Klassen die du dafür benötigst könnten z.B. so aussehen:

    class Waffe
    {
    public:
    Waffe(std::string C_name, int C_dmg,int C_kosten)
    std::string name;
    int dmg,kosten;
    }
    class Waffenangebot
    {
    public:
    void getListe(void)
    {
    for(int i = 0; i < Waffenliste.size();i++)
    {
    std::cout << "Name: " << Waffenliste[i].name << "(Dmg " << Waffenliste[i].dmg << ", Kosten " << Waffenliste[i].kosten << std::endl");
    }
    void addWaffe(Waffe blabla);
    privat:
    std::vector<Waffe> Waffenliste;
    }

    Dann im Programm immer eine Zeile aus der Textdatei auslesen und in ein Objekt des Typs Waffe einspeichern und das in die Klasse Waffenangebot einfügen.
    Fertig.

    Schau dir dazu die Klasse ifstream an, sowie die Klasse vector.



  • Oder habe ich jetzt dein Problem missverstanden? Die Auswahl ist dann eigentlich kein Problem mehr, kannst bei der Ausgabe ja noch eine Nummer davorschreiben, so dass der Nutzer weiß welche Nummer welcher Waffen entspricht.



  • Wenn ich deine Frage richtig verstanden habe, dann willst du über 100 Waffen, aber die Waffen nicht aufschreiben.
    Das funktioniert so nicht.
    Aber wie mein Vorposter schon schrieb könntest du die Waffenliste in eine Datei auslagern und sie über einen fstream aus dieser datei holen.

    gruß
    syntax



  • Zuerst mal Danke ich werde mir das alles heute und Morgen genau durch lesen und es ausprobieren 😃

    @Syntax_error
    Doch die Waffen möchte ich aufschreiben, aber ich möchte nicht so viel Code haben, sprich irgend wo wird alles angezeigt und mit Switch die Auswahl getroffen, (das ist so gut jedoch..) dann habe ich ja einen Rückgabewert (int c)
    welcher dann jede einzelne Waffe mit:

    IF(c=zahl der 1.waffe, zahl der 2.waffe..., zahl der 100.waffe)
    {
          waffen werte auf variabeln schreiben;
    }
    

    überprüft. Dieser Code der praktisch nur aus IF besteht möchte ich irgendwie kleiner machen ist dies überhaupt möglich?

    @Namenloser324
    Wenn ich deine Variante nehme habe ich ja dann nur den Code der Waffen aus dem Programm rausgenommen und in einem Textfile jedoch muss dann dies auswahl wieder (nach meiner bis jetzt verwendeten Variante) mit IF erfolgen.
    Sehe ich das so richtig?

    Gruss

    nimda4



  • Nee, das geht mit ein paar Zeilen und deckt alle Fälle ab.

    Klasse entsprechend anpassen:

    if(Waffenliste.Waffen[EINGABE].kosten <= Geld)
    {
    Geld = Geld-[...].kosten;
    cout << "Waffe " << "Waffenliste.Waffen[EINGABE].name << " gekauft" << endl;
    }
    else
    cout << "Zu wenig Geld" << endl;



  • Danke Namenloser324

    Jetzt habe ich nru das Problem das mich das ganze ziemlich verwirrt ^^-.-

    Was eine Klasse ist udn ein Objekt und wie ich sie erstelle weiss ich, jedoch verstehe ich das mit der Liste und dem einlesen nicht so ganz.
    Ich habe jetzt eine Liste(waffenliste.txt) die wie du gesagt ahst wie folgt aus sieht:

    Schwert 19 200
    Armbrust 10 100
    Dolch 14 150

    Ich werde mir jetzt ifstream, vector und fstream ansehen und mich noch mal melden sollte das Problem immer noch bestehen.

    Vielen Dank für eure Hilfe, Ihr habt mir schon so gut geholfen in nur so kurzer Zeit 😃

    Gruss & Merci

    nimda4



  • So gerade eben habe ich mri fstream angeschaut und weiss nun wie ich ein text file einlesen kann, jedoch wie kann ich die Texte beim Lerzeichen trennen udn eineln auf die Klasse speichern :O?

    Hab leider nix gescheites mit der sufu gefunden (villeicht bin ich einfach zu blöd -.-)
    Hab erst gerade mit dem Programmieren angefangen und verzweifle langsamm^^

    Gruss

    nimda4



  • Okei hab jetzt gefunden wie ich es trennen kann

    getline(myfile,line,' ');

    doch wie kann ich die einzelnen einträge nun speichern?



  • Tja, denk drüber nach, du lädst jetzt ja zeilenweise in einen string.
    Strins haben standardmäßig bereits funktionen zum verarbeiten bzw bearbeiten des strings, schau mal hier:

    http://www.cplusplus.com/reference/string/string/

    Was du brrauchen könntest ist z.B. substr, damit kannste aus einem string teile ausschneiden. Ferner wirst du http://www.cplusplus.com/reference/string/string/find/ das hier brauchen, oder eine ähnliche FUnktion. Damit kannst du nach Leerzeichen suchen und mittels substr alles bis zum ersten Leerzeichen ausschneiden. Dann löscht du am besten eben diesen substring und kannst somit die prozedur einfach weiterführen d.h. wiederholen.
    Zum löschen von Teilen des Strings spielst du am besten mit http://www.cplusplus.com/reference/string/string/erase/ rum



  • Achso, am besten du liest eine ganze Zeile ein und weist getline an bitte bis zum Zeichen "\n" einzulesen(das zeichen wird immer dann generiert wenn man enter drückt in einer Textdatei, ist sinngemäß identisch mit std::endl).



  • Eine Sache habe ich noch vergessen:

    Wenn du mit den Zahlen(Schaden, Dmg) weiterrechnen möchtest musst du die strings erstmal in Zahlen umwandeln, das geht am leichtesten mit string streams, schau einfach bei google mal nach, ist aber ganz einfach, siehe z.B. hier
    http://www.velocityreviews.com/forums/t283255-string-to-integer.html



  • Und warum wieder getline + string zerpflücken, wenn es ein einfaches cin >> var täte?



  • @Namenloser324

    Zuerst mal Danke für die Info, aber hab ich bereits gemacht 😉

    2. Ich finde gut das du mir nicht gleich die Lösung sagst, sonst würde ich erlich gesagt das ganze gar nicht merh anschauen ^^

    Hab mir jetzt vector, fstream/ifstream angesehen jedoch komme ich nicht ganz weiter.

    Ich hab jetzt einen string eingelesen aus der Textdatei und der sieht ja dann ungefähr so aus:

    schwert
    18
    300
    
    dolch
    14
    200
    

    Jetzt muss ich die Daten doch (so wie ich das verstanden habe) zu einem Objekt der Klasse "Waffe" hinzufügen.

    Normalerweise mache ich das ja mit z.b:

    waffe schwert;
    schwert.dmg=18;
    schwert.name="Schwert";
    schwert.Preis=300;
    

    Wenn das soweit richtig ist(ist es das?^^), wie kann ich dann machen das mir diese Werte automatisch rein geschrieben werden?

    Wenn du nicht gleich die Lösung geben willst dann bitte wenigstens einen Tipp, bin einwenig am verzweifeln 😞 ^^



  • Und was ist eigentlich die Waffenliste (die klasse) genau?
    Also was für Objekte gehören da rein?
    Oder brauche ich die MEthoden für die Objekte der Klasse Waffe?

    Das verwirrt mich ein wenig.

    Gruss

    nimda4



  • arghonaut schrieb:

    Und warum wieder getline + string zerpflücken, wenn es ein einfaches cin >> var täte?

    bei cin musst du ja selbst die Enter tase besätigen (so weit mir bekannt)
    aber ich lese die Werte ja aus einer liste ein, geht das etwa auch mit cin aus eienr Liste?

    Gruss Nimda4



  • arghonaut schrieb:

    Und warum wieder getline + string zerpflücken, wenn es ein einfaches cin >> var täte?

    Keine Ahnung, benutze ich nie. Dann halt damit, mir egal. Soll er halt rumprobieren.



  • nimda4 schrieb:

    Jetzt muss ich die Daten doch (so wie ich das verstanden habe) zu einem Objekt der Klasse "Waffe" hinzufügen.

    Normalerweise mache ich das ja mit z.b:

    waffe schwert;
    schwert.dmg=18;
    schwert.name="Schwert";
    schwert.Preis=300;
    

    Wenn das soweit richtig ist(ist es das?^^), wie kann ich dann machen das mir diese Werte automatisch rein geschrieben werden?

    Wenn du nicht gleich die Lösung geben willst dann bitte wenigstens einen Tipp, bin einwenig am verzweifeln 😞 ^^

    Das ist zwar richtig, aber umständlich.

    Du schreibst dir z.B. einen Konstruktor in welchem du die strings bzw. die Werte als Parameter übergibst und der Konstruktor bastelt dir daraus automatisch das entsprechende Objekt bzw. lädt das Objekt mit den Daten.
    Hab das ganze bereits programmiert, ist zwar hässlich da keine Lust groß nachzudenken, aber funktioniert.

    WARNUNG: nicht als beispiel für ordentliches programmieren nehmen, ist sehr geschludert und unschön programmiert. Habe z.B. praktisch keine Kontrollen die den Input auf Fehler prüfen oder ähnliches.

    #include <iostream>
    #include <fstream>
    #include <vector>
    #include <string>
    
    using namespace std;
    
    class Waffe
    {
        public:
        Waffe(string CName,string CDmg,string CKosten){Name = CName;Dmg = CDmg;Kosten=CKosten;}
        string Name,Dmg,Kosten;
    };
    class Waffenliste
    {
        public:
        void add(Waffe item)
        {
            Liste.push_back(item);
        }
        vector<Waffe> Liste;
    };
    int main()
    {
        Waffenliste liste;
        ifstream file("waffen.txt");
        if(file.good())
        {
    
            while(!file.eof())
            {
            vector<string> zeile;
            string line;
            getline(file,line);
            do
            {
    //generiert Substring und fügt den gleich dem vektor hinzu
                zeile.push_back(line.substr(0,line.find(" ")));
    //wenn danach noch ein leerzeichen kommt löscht er bis zu diesem sonst alles
                if(line.find(" ")!= string::npos)
                line.erase(0,line.find(" ")+1);
                else
                line.erase();
            }
            while(!line.empty());
            liste.add(Waffe(zeile[0],zeile[1],zeile[2]));
            }
    
        }
        file.close();
        for(unsigned int i = 0 ; i<liste.Liste.size();i++)
        cout << "Name: " << liste.Liste[i].Name << "(Dmg " << liste.Liste[i].Dmg << ",Kosten " << liste.Liste[i].Kosten << ")" << endl;
    
        return 0;
    }
    

    Mit der cin variante die vorgeschlagen worden ist geht das aber schöner, aber ich mag cin nicht, kA wieso.



  • nimda4 schrieb:

    arghonaut schrieb:

    Und warum wieder getline + string zerpflücken, wenn es ein einfaches cin >> var täte?

    bei cin musst du ja selbst die Enter tase besätigen (so weit mir bekannt)
    aber ich lese die Werte ja aus einer liste ein, geht das etwa auch mit cin aus eienr Liste?

    Sorry, klar, war zu schnell abgeschickt. Die Intention sollte aber klar sein, denn den operator>> gibt es für alle streams, somit auch für den ifstream.
    Grob skizziert:

    ifstream waffen_file("blubb.txt");
    while(Zeilen vorhanden) {
        int schaden, preis;
        string name;
        waffen_file >> name >> schaden >> preis;
    }
    


  • Sorry, aber wäre es nicht sinnvoller lieber mal nach einem Buch zu greifen und die Grundlagen zu lernen anstatt dich irgendwie mit einzelnen Code-Schnipseln "durchzuschlagen" ? Villeicht lässt mich da mein Sinn für Pädagogik im Stich, aber falls der Threadersteller daran interessiert ist, wirklich C++ zu lernen wäre das wohl das Sinnvollste.

    Ich meine :

    #include <stdio.h> 
    #include <tchar.h> 
    #include <stdlib.h> 
    #include <string> 
    #include <time.h> 
    #include <csetjmp> 
    #include <stddef.h> 
    #include <iostream> 
    #include <conio.h> 
    #include <dos.h> 
    #include <conio.h> 
    #include <Windows.h>
    


  • Namenloser324 schrieb:

    nimda4 schrieb:

    Jetzt muss ich die Daten doch (so wie ich das verstanden habe) zu einem Objekt der Klasse "Waffe" hinzufügen.

    Normalerweise mache ich das ja mit z.b:

    waffe schwert;
    schwert.dmg=18;
    schwert.name="Schwert";
    schwert.Preis=300;
    

    Wenn das soweit richtig ist(ist es das?^^), wie kann ich dann machen das mir diese Werte automatisch rein geschrieben werden?

    Wenn du nicht gleich die Lösung geben willst dann bitte wenigstens einen Tipp, bin einwenig am verzweifeln 😞 ^^

    Das ist zwar richtig, aber umständlich.

    Du schreibst dir z.B. einen Konstruktor in welchem du die strings bzw. die Werte als Parameter übergibst und der Konstruktor bastelt dir daraus automatisch das entsprechende Objekt bzw. lädt das Objekt mit den Daten.
    Hab das ganze bereits programmiert, ist zwar hässlich da keine Lust groß nachzudenken, aber funktioniert.

    WARNUNG: nicht als beispiel für ordentliches programmieren nehmen, ist sehr geschludert und unschön programmiert. Habe z.B. praktisch keine Kontrollen die den Input auf Fehler prüfen oder ähnliches.

    #include <iostream>
    #include <fstream>
    #include <vector>
    #include <string>
    
    using namespace std;
    
    class Waffe
    {
        public:
        Waffe(string CName,string CDmg,string CKosten){Name = CName;Dmg = CDmg;Kosten=CKosten;}
        string Name,Dmg,Kosten;
    };
    class Waffenliste
    {
        public:
        void add(Waffe item)
        {
            Liste.push_back(item);
        }
        vector<Waffe> Liste;
    };
    int main()
    {
        Waffenliste liste;
        ifstream file("waffen.txt");
        if(file.good())
        {
    
            while(!file.eof())
            {
            vector<string> zeile;
            string line;
            getline(file,line);
            do
            {
    //generiert Substring und fügt den gleich dem vektor hinzu
                zeile.push_back(line.substr(0,line.find(" ")));
    //wenn danach noch ein leerzeichen kommt löscht er bis zu diesem sonst alles
                if(line.find(" ")!= string::npos)
                line.erase(0,line.find(" ")+1);
                else
                line.erase();
            }
            while(!line.empty());
            liste.add(Waffe(zeile[0],zeile[1],zeile[2]));
            }
    
        }
        file.close();
        for(unsigned int i = 0 ; i<liste.Liste.size();i++)
        cout << "Name: " << liste.Liste[i].Name << "(Dmg " << liste.Liste[i].Dmg << ",Kosten " << liste.Liste[i].Kosten << ")" << endl;
    
        return 0;
    }
    

    Mit der cin variante die vorgeschlagen worden ist geht das aber schöner, aber ich mag cin nicht, kA wieso.

    o.O schludrig? sowas nennst du schludrig?
    OMG jetzt fühl ich mich dumm -.-^^

    Das ist hamemr von dir ich hab mir jetzt das ganze angesehen und versucht nach zuvollziehen und habe daher noch ein paar kleine Fragen:

    1. vector<waffe> Liste; und vector<string> zeile; was machen die genau?

    2. liste.add(Waffe(zeile[0],zeile[1],zeile[2])); Verstehe ich so: fügt Schwert, 18, 300 zur liste hinzu als Objekt Waffe. Ist das richtig?

    3. for(unsigned int i = 0 ; i<liste.Liste.size();i++); Bildet die Liste oder?

    Ich hab das Programm gestartet, es geht auf verschwindet dann wieder (trotz system("pause");) und es erscheint ein Pop Up mit dem Text:
    "Debug Assertion Failed!

    Programm..\rpg\rpg\Debug\rpg.exe
    Filec:\program files(x86)\microsoft visual studio
    10.0\vc\include\vector
    Line932

    Expresion vector subscription out of range

    For information on how your programm can cause an assertion failure, see the Visual C++ documentation on asserts.

    (Press Retry to debug the application)"

    Wie da steht hat das ja demnach etwas mit dem vector zutun?

    Vielen Vielen Dank für deine Hilfe bis jetzt du bist mein Held

    Gruss

    nimda4


Anmelden zum Antworten