Der beste Weg zum Spieleprogrammieren



  • Meinst du soetwas?

    #include <iostream>
    #include <map>
    #include <conio.h>
    
    using namespace std;
    
    int main()
    {
    	int zahl[5];
    
    	cout << "Gib 5 Zahlen ein\n";
    	for (int i = 0; i != 5; i++)
    		cin >> zahl[i];
    
    	map<char, int> _map;
    	for (int i = 0; i != 5; i++)
    		_map[i] = zahl[i];
    
    	for (int i = 0; i != 5; i++)
    		cout << "_map[" << i << "] ist: " << zahl[i] << endl;
    
    	getch();
    	return 0;
    }
    

    Oder habe ich da etwas falsch verstanden oder einen anderen Fehler gemacht?

    Weiterhin danke für Hilfe.

    -Skotchy



  • Skotchy schrieb:

    Meinst du soetwas?

    #include <iostream>
    #include <map>
    #include <conio.h> // kein Standardheader, raus damit, da für Aufgabe irrelevant ;)
    
    #include <limits> // std::numeric_limits<T>
    #include <ostream> // operator<< für std::ostream
    
    using namespace std;
    
    int main()
    {
    	int zahl[5];
    
    	cout << "Gib 5 Zahlen ein\n";
    	for (int i = 0; i != 5; i++)
    		cin >> zahl[i];
    
    	map<char, int> _map; // leading underscores sind reserviert, _map ist zudem nichtsaussagend
    	for (int i = 0; i != 5; i++)
    		_map[i] = zahl[i];
    
    	for (int i = 0; i != 5; i++)
    		cout << "_map[" << i << "] ist: " << zahl[i] << endl;
    
    	getch(); // --> cin.clear(); cin.ignore(numeric_limits<streamsize>::max(), '\n'); cin.getline();
    	return 0;
    }
    

    Oder habe ich da etwas falsch verstanden oder einen anderen Fehler gemacht?

    Weiterhin danke für Hilfe.

    -Skotchy

    Ich hab mal ein paar Sachen markiert, die du demnächst ändern solltest.

    In der Aufgabe war aber nicht das Einlesen von 5 Werten, sondern das Auslesen von beliebig vielen Datenpaaren aus einer Datei gefragt 😉

    Tipp: ofstream und getline zum Einlesen in einen string , zeilenweise Verarbeitung der Daten, Einfügen in die map , Iterieren über die Map, um die Ergebnisse auszugeben



  • Sorry, ifstream meinte ich natürlich 😉



  • helper() {cout<<MY_ schrieb:

    In der Aufgabe war aber nicht das Einlesen von 5 Werten, sondern das Auslesen von beliebig vielen Datenpaaren aus einer Datei gefragt 😉

    Aus welcher Datei soll ich denn Auslesen?
    Muss ich in dem Programm erst eine Datei erstellen die ich dann Auslesen soll?

    Danke für eure Hilfe.

    -Skotchy



  • Schreib dir doch einfach im Editor eine kleine Testdatei. Dafür brauchst du kein Programm schreiben.



  • Ok, nun hab ich zwei Programme zusammengebastelt:

    Einmal das:

    #include <iostream>
    #include <map>
    #include <limits>
    #include <fstream>
    #include <string>
    
    using namespace std;
    
    int main()
    {
    	string sText;
    	string::iterator itText;
    
    	map<char, string> mText;
    	ifstream MeineDatei ("TestDokument.txt");
    
    	if (MeineDatei.is_open())
    	{
    		getline (MeineDatei, sText);
    		int DatenGroesse = sText.size();
    		for (int i = 0; i != DatenGroesse; i++)
    		{
    			mText[i] = sText;
    		}
    		MeineDatei.close();
    	}
    	else
    		cout << "Fehler";
    
    	for (itText = sText.begin(); itText < sText.end(); itText++)
    	{
    		cout << *itText;
    	}
    
    	cin.clear();
    	cin.ignore(numeric_limits<streamsize>::max(), '\n');
    	return 0;
    }
    

    und einmal das:

    #include <iostream>
    #include <map>
    #include <limits>
    #include <fstream>
    #include <string>
    
    using namespace std;
    
    int main()
    {
    	string sText;
    
    	map<char, string> mText;
    	ifstream MeineDatei ("TestDokument.txt");
    
    	if (MeineDatei.is_open())
    	{
    		getline (MeineDatei, sText);
    		int DatenGroesse = sText.size();
    		for (int i = 0; i != DatenGroesse; i++)
    		{
    			mText[i] = sText[i];
    			cout << mText[i];
    		}
    		MeineDatei.close();
    	}
    	else
    		cout << "Fehler";
    
    	cin.clear();
    	cin.ignore(numeric_limits<streamsize>::max(), '\n');
    	return 0;
    }
    

    Beide haben den Fehler das sie nur die erste Zeile des Dokuments wiedergeben.
    Wo ist da der Fehler und hab ich dieses Mal die Aufgabe erfüllt(abgesehen von dem Fehler 😉 )?

    Weiterhin danke für eure Hilfe.

    -Skotchy



  • Jain. Immerhin liest du jetzt aus einer Datei, so wie es vorgesehen war. Aber du hast die std::map leider noch gar nicht verstanden. Zudem würde sich bei dieser Aufgabe der operator >> zum Auslesen aus der Datei anbieten. Und es war gefordert, den "Auslesen" Teil in eine Funktion zu packen.

    Aber wie gesagt, das Hauptproblem besteht einfach darin, dass du die std::map nicht verstanden hast, die solltest du dir noch mal angucken.
    Du hast dich wohl etwas zu nah an diesem Beispiel gehalten, scheinbar ohne wirklich verstanden zu haben, wie die map funktioniert. Ein Tipp: Sowohl Schlüssel als auch Wert sollten hier vom Typ std::string sein!

    Und kleine Schönheitsfehler:
    globales using namespace std;, pack das lieber in die Funktion rein oder schreibe gleich std::.
    Und "Fehler" ist keine aussagekräftige Fehlermeldung.

    Edit:
    Und nenne deine Variablen ruhig einfach text oder so, ein "Typen-Prefix", auch als Ungarische Notation bekannt, ist nicht gern gesehen.

    Edit2:
    Und warum schließt du deine Datei innerhalb der Schleife? 😮 Warum liest du nur ein mal etwas aus?



  • Wenn dort mal eine Schleife wäre 😉



  • Th69 schrieb:

    Wenn dort mal eine Schleife wäre 😉

    LOL, irgendwie hat mein Auge da eine Schleife hingebaut.



  • cooky451 schrieb:

    Th69 schrieb:

    Wenn dort mal eine Schleife wäre 😉

    LOL, irgendwie hat mein Auge da eine Schleife hingebaut.

    Macht man das jetzt so? Augmented Programming oder was? 😉 😃



  • So nun müsste es doch richtig sein:

    #include <iostream>
    #include <map>
    #include <limits>
    #include <fstream>
    #include <string>
    
    void Auslesen()
    {
    	using namespace std;
    
    	string Text;
    
    	ifstream MeineDatei;
    	MeineDatei.open ("TestDokument.txt");
    	map <string, string> text;
    
    	while (MeineDatei.good())
    	{
    		text["meintext"] = MeineDatei.get();
    		cout << text["meintext"];
    	}
    
    	MeineDatei.close();
    }
    
    int main()
    {
    	using namespace std;
    	ifstream MeineDatei;
    	MeineDatei.open ("TestDokument.txt");
    	if (MeineDatei.is_open())
    		Auslesen();
    
    	else
    		cout << "Fehler beim Auslesen der Daten!" << endl 
    		<< "Bitte pruefen sie ob \"TestDokument.txt\" existiert und im richtigen Ordner ist!";
    
    	MeineDatei.close();
    	cin.clear();
    	cin.ignore(numeric_limits<streamsize>::max(), '\n');
    }
    

    Ich habe die Fehlermeldung aussagekräftiger gemacht,
    eine Void-Funktion benutzt (zuerst dachte ich das ich alles in der main-Funktion ausgeben sollte),
    den Fehler behoben bei dem ich nur die erste Zeile zu lesen bekam
    und (so denke ich) habe map verstanden (ich lasse mich auch gern eines besseren belehren).

    Ich freue mich auch über eine Korrektur der 'Schönheitsfehler' oder auch anderen Fehlern, von denen es bestimmt genug gibt.

    Weiterhin danke für eure Hilfe.

    -Skotchy



  • Skotchy schrieb:

    und (so denke ich) habe map verstanden (ich lasse mich auch gern eines besseren belehren).

    Dann werde ich das mal machen. 🙂
    Bedenke noch einmal:

    map<string, string> m;
    m[SCHLUESSEL] = WERT.
    

    Wie sieht jetzt noch gleich die Datei aus?

    Die Datei schrieb:

    Schlüssel Wert
    Schlüssel Wert
    ...
    

    So wie du es jetzt machst, änderst du immer nur den Wert des Schlüssels "meintext".

    Dann noch kleine Anmerkungen:
    ifstream hat einen Konstruktor, da brauchst du dann kein open mehr:

    ifstream datei("text.txt");
    

    Das close am Ende kannst du hier auch sparen, das macht der Destruktor. (RAII ist schon was Tolles. :p)

    Zudem sollte die Funktion (hätte ich vielleicht deutlicher machen sollen) nur auslesen, aber nichts ausgeben. Das soll dann wieder in der main() geschehen.



  • Und die nächste Version des Programms ist raus:

    #include <iostream>
    #include <map>
    #include <limits>
    #include <fstream>
    #include <string>
    
    void Auslesen()
    {
        using namespace std;
    
    	int i = 0;
    
        ifstream MeineDatei ("TestDokument.txt", ios::in);
        map <int, string> text;
    
    	while(getline (MeineDatei, text[i]))
    		i++;
    
    	for (int j = 0; j != text.size() - 1; j++)
    		cout << "Text " << j << " ist " << text[j] << endl;
    }
    
    int main()
    {
        using namespace std;
        ifstream MeineDatei ("TestDokument.txt");
        if (MeineDatei.is_open())
    	{
            Auslesen();
    
    	}
    
        else
            cout << "Fehler beim Auslesen der Daten!" << endl
            << "Bitte pruefen sie ob \"TestDokument.txt\" existiert und im richtigen Ordner ist!";
    
    	cin.clear();
        cin.ignore(numeric_limits<streamsize>::max(), '\n');
    }
    

    Allerdings habe ich immer noch ein Problem:
    ich bekomme die maps nicht aus der Funktion und kann sie deswegen nich in der mein() Funktion ausgeben.
    Allerdings habe ich map jetzt verstanden (oder?!).

    Weiterhin danke für eure Hilfe.

    -Skotchy



  • Skotchy schrieb:

    Allerdings habe ich immer noch ein Problem:
    ich bekomme die maps nicht aus der Funktion und kann sie deswegen nich in der mein() Funktion ausgeben.

    Dann lies noch mal etwas über Rückgabewerte oder Referenzen oder Pointer. (Ein Pointer ist hier allerdings eher C-Stil und nicht zu bevorzugen, aber es funktioniert.)

    Skotchy schrieb:

    Allerdings habe ich map jetzt verstanden (oder?!).

    Ich fürchte nicht. Um das noch mal klar zu machen, der Dateiaufbau:

    Schlüssel Wert
    Schlüssel Wert
    ..
    

    Beides sind Strings, du brauchst also eine std::map<std::string, std::string>!

    Und getline() ist hier, wie ich bereits erwähnt hatte, nicht gerade das Optimum. Denn getline() liest, wie der Name schon vermuten lässt, eine ganze Zeile auf einmal aus. Dann musst du allerdings noch den Schlüssel von dem Wert trennen, das ist unnötig kompliziert. Guck dir noch mal operator >> an.



  • So jetzt hab ich die map aus der Funktion rausbekommen, allerdings habe ich jetzt den ganzen Text in map bzw. String.
    Und wie ich den Operator>> hier anwenden soll weiß ich leider auch nicht. Ich wüsste nur wie ich den Operator>> mit cin anwenden könnte.

    Hier aber erstmal meine nächste Version des Programms:

    #include <iostream>
    #include <map>
    #include <limits>
    #include <fstream>
    #include <string>
    #include <Windows.h>
    
    void Auslesen(std::string &t)
    {
        using namespace std;
    	ifstream MeineDatei ("TestDokument.txt");
    	while (!MeineDatei.eof()){
    		t += MeineDatei.get();
    //		t >> MeineDatei.get();
    	}
    }
    
    int main()
    {
        using namespace std;
        ifstream MeineDatei ("TestDokument.txt");
        if (MeineDatei.is_open())
    	{
    		map <string, string> Text;
            Auslesen(Text["Text"]);
    
    		cout << Text["Text"];
    	}
    
        else
            cout << "Fehler beim Auslesen der Daten!" << endl
            << "Bitte pruefen sie ob \"TestDokument.txt\" existiert und im richtigen Ordner ist!";
    
    	cin.clear();
        cin.ignore();
    }
    

    Weiterhin danke für eure Hilfe.

    -Skotchy



  • Skotchy schrieb:

    So jetzt hab ich die map aus der Funktion rausbekommen,

    Zumindest ist das mit der Referenz ein brauchbarer Ansatz. Jetzt überlege, wie du wirklich die std::map und nicht nur einen String nutzen kannst.

    Skotchy schrieb:

    Und wie ich den Operator>> hier anwenden soll weiß ich leider auch nicht. Ich wüsste nur wie ich den Operator>> mit cin anwenden könnte.

    Hm.. wie wäre es denn, sich mal das Beispiel anzusehen was man auf meinem Link oben betrachten kann? Ein Tipp: Die Anwendung sieht genau so aus wie bei std::cin.

    Aber die std::map hast du immer noch nicht verstanden. Du liest weiterhin alles in den Schlüssel "Text" ein.



  • cooky451 schrieb:

    Jetzt überlege, wie du wirklich die std::map und nicht nur einen String nutzen kannst.

    also muss ich:

    void Auslesen (std::map<std::string, std::string> &text)
    

    benutzen, oder liege ich da falsch?

    cooky451 schrieb:

    Ein Tipp: Die Anwendung sieht genau so aus wie bei std::cin.

    Also:

    ifstream& >> text["test"]
    

    oder lige ich hier(wieder) falsch? Ich habe das schon ausprobiert, aber ich bekomme immer '>>' rot unterstrichen und 'Error: Es wurde ein Bezeichner erwartet.'
    Auserdem wüsste ich nicht wie ich den String "test" ändern könnte damit ich beliebig viele Wörter aus dem Dokument Auslesen kann.
    Oder (so wie ich map verstanden habe): weiß ich nicht wie ich den Schlüssel("test") ändern könnte um ihnen dann die Werte(Wörter/Zeilen) zuzuordnen, weil sie im string-format vorliegen( mit int könnte ich den Schlüssel in einer for-Schleife ändern).

    Über weitere Tipps würde ich mich freuen und weiterhin danke für eure Hilfe.

    -Skotchy



  • Skotchy schrieb:

    also muss ich:

    void Auslesen (std::map<std::string, std::string> &text)
    

    benutzen, oder liege ich da falsch?

    Das ist so korrekt, fehlt nur noch der Dateiname als zweiter Parameter. Du könntest die map zwar auch aus der Funktion zurückgeben (std::map<std::string, std::string> Auslesen(const char *dateiname)), aber das ist so absolut in Ordnung.

    Skotchy schrieb:

    Also:

    ifstream& >> text["test"]
    

    oder lige ich hier(wieder) falsch? Ich habe das schon ausprobiert, aber ich bekomme immer '>>' rot unterstrichen und 'Error: Es wurde ein Bezeichner erwartet.'

    Aha, da liegt das Problem. std::cin ist eine Instanz von istream. Du schreibst ja auch nicht istream >> s. Ist der Groschen gefallen?

    std::ifstream infile("test.txt");
    std::string s;
    infile >> s;
    

    Skotchy schrieb:

    Auserdem wüsste ich nicht wie ich den String "test" ändern könnte damit ich beliebig viele Wörter aus dem Dokument Auslesen kann.
    Oder (so wie ich map verstanden habe): weiß ich nicht wie ich den Schlüssel("test") ändern könnte um ihnen dann die Werte(Wörter/Zeilen) zuzuordnen, weil sie im string-format vorliegen( mit int könnte ich den Schlüssel in einer for-Schleife ändern).

    Wenn ich dir das jetzt einfach sage, habe ich die Aufgabe ja für dich gelöst. Aber ein Tipp: Du kannst auch eine Variable benutzen! Also Folgendes ist möglich:

    std::map<std::string, std::string> m;
    std::string s = "Hallo, ";
    m[s] = "Welt!";
    


  • So habe ich das jetzt 'gelöst':

    #include <iostream>
    #include <map>
    #include <limits>
    #include <fstream>
    #include <string>
    
    void Auslesen(std::map<std::string, std::string> &text, std::string s)
    {
        using namespace std;
    	int i = 0;
    	ifstream MeineDatei ("TestDokument.txt");
    
    	while (!MeineDatei.eof()){
    		s = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"[i];
    		MeineDatei.get();
    		MeineDatei >> text[s];
    		++i;
    	}
    }
    
    int main()
    {
        using namespace std;
    
    	string schluessel;
    	map <string, string> Text;
        ifstream MeineDatei ("TestDokument.txt");
        if (MeineDatei.is_open())
    	{
            Auslesen(Text, schluessel);
    
    		for(int i = 0; i != Text.size(); ++i)
    		{
    			schluessel = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"[i];
    			cout << Text[schluessel];
    		}
    	}
    	else
            cout << "Fehler beim Auslesen der Daten!" << endl
            << "Bitte pruefen sie ob \"TestDokument.txt\" existiert und im richtigen Ordner ist!";
    
    	cin.clear();
        cin.ignore();
    }
    

    Und irgendwo habe ich etwas vergessen oder übersehen oder sonst etwas, denn ich habe 2 Fehler, die hoffentlich meine letzten sind bzw. in diesem Programm sein werden.
    Und zwar:
    1. wird der erste Buchstabe nicht ausgegeben.
    2. werden keine Leerzeichen und Absätze erkannt/benutzt.

    Und noch eine Frage: ist die Lösung für den Schlüssel mit 'schluessel = "ABC..."[i];' eine gute bzw passend Lösung für die Namensgebung oder gibt es da bessere?

    Weiterhin danke für eure Hilfe.

    -Skotchy



  • Skotchy schrieb:

    Und noch eine Frage: ist die Lösung für den Schlüssel mit 'schluessel = "ABC..."[i];' eine gute bzw passend Lösung für die Namensgebung oder gibt es da bessere?

    Tja, du scheinst die map<> jetzt zwar irgendwie verstanden zu haben, aber scheinbar die Aufgabenstellung nicht. Du nutzt als Schlüssel wieder im Programm selbst vorgegebene Dinge. Bedenke den Aufbau der Datei!

    Schlüssel Wert
    Schlüssel Wert
    ...
    

    Für die Ausgabe in der main()-Funktion solltest du dir Iteratoren ansehen.

    (Falls du lieber erstmal eine "Musterlösung" sehen möchtest, weil du das Gefühl hast so nicht weiter zu kommen sag Bescheid.)


Anmelden zum Antworten