error C2228: Links von ".write" muss sich eine Klasse/Struktur/Union befinden [gelöst]



  • Ich habe schon nach dem Fehlercode gegoogelt aber leider hat niemand genau mein problem und die ähnlichen Fehler und Lösungen versteh ich nicht wirklich, da ich mich nicht so gut auskenne.
    Ich glaube zu verstehen, dass ich den write/close/Output.. Befehl nicht in eine Funktion schreiben darf. Aber warum und wie kann man das Umgehen? Hier nein kleiner Auschnitt aus dem Programmcode:

    [code]//Highscore ausgeben
    int HighscoreAusgeben (int Highscore)
    {
    				//Datei  öffnen und hineinschreiben
    				ofstream Output ("Highscore.hsc", ios::binary);
    				Output.write ((char*) &Highscore, sizeof (Highscore));
    				//Datei schließen
    				Output.close ();
    
    				//Datei öffnen und auslesen
    				ifstream Input ("Highscore.hsc", ios::binary);
    				Input.read ((char*) &Highscore, sizeof (Highscore));
    				//Datei schließen
    				Input.close ();
    
    				cout << "Der aktuelle Highscore liegt bei ";
    				cout << Highscore << "Punkten " << endl;
    				//cout << "von " << SpielerName <<"\n\n";
    				return 0;
    }//Highscore auslesen[/code]
    

    (mit dem Code darstellen kenn ich mich noch nicht so aus, ich hoffe es passt so)

    Das ganze basiert auf dem Spiel Zahlenraten aus dem Buch C++ Für Spieleprogrammierer von Heiko Kalista. Ich wollte es um eine Highscore Speicherung erweitern, nachdem ich das Buch einigermaßen durchgearbeitet habe.
    Schon mal Danke im Voraus



  • #include <fstream>
    


  • Tachyon schrieb:

    #include <fstream>
    

    cool danke hat sofort funktioniert.
    Wann muss ich das immer einfügen?
    Also wann brauch ich das?
    Nicht das ich nochmal etwas änhliches fragen muss.

    ups funktioniert doch nicht jetzt zeigt er zwar keinen Fehler mehr an aber im Programm zeigt er mir keinen Highscore an.



  • Sobald du etwas auf diesem Header benutzt. Wenn du lediglich Zeiger o.ä. deklarieren willst, dann würden Vorwärtsdeklarationen reichen, aber bei den Standardsachen ist das normalerweise aufwendiger zu integrieren. Es gibt Header, die genau für das gemacht sind, aber ich habe bist jetzt nocht nicht wirklich Code gesehen, wo die gebraucht werden. Also kannst du immer den normalen Header includen.

    Zu vermerken ist, dass du nicht immer einen Fehler bekommst, wenn du den Hader nicht includest. Das hat den Grund, dass einige Header, die du includest eventuell noch andere includen. Dann kompiliert dein Code ebenfalls ohne Probleme. (Das muss aber nicht immer so sein, da die Implementierung vlt. mal andere Header benutzt, also immer includen, auch wenn es keinen Fehler gibt).



  • drakon schrieb:

    Es gibt Header, die genau für das gemacht sind, aber ich habe bist jetzt nocht nicht wirklich Code gesehen, wo die gebraucht werden. Also kannst du immer den normalen Header includen.

    Wenn möglich, würde ich schon <iosfwd> einsetzen. Ansonsten sind Vorwärtsdeklarationen bei den Standardsachen (z.B. std::string ) oft recht heikel, weil das Templates sind und die Implementierung auch weitere Default-Templateparameter bereitstellen darf. Bei eigenen Headern ist es natürlich noch viel wichtiger, auf Kompilierzeit-Abhängigkeiten zu achten.



  • tut mir leid aber ich glaub ich bin ein bisschen zu doof bei den letzten zwei Beiträgen versteh ich nicht wirklich etwas.
    Könntet ihr das nochmal etwas leichter erklären?
    Danke



  • Was verstehst du denn nicht?

    Mit einer (Vorwärts-)Deklaration macht man den Compiler bekannt, dass es einen Typ mit diesem Namen gibt, ohne die eigentliche Definition zu liefern. Das ist sinnvoll, weil man sich so Abhängigkeiten spart (im Header steht weniger Code, somit werden wahrscheinlich auch weniger andere Header benötigt). Dadurch wird die Komplexität von Klassenbeziehungen und somit auch die Kompilierzeit gesenkt. Ausserdem kann man auf diese Weise die Implementierung vor dem Benutzer verbergen.

    // Schlecht: vollständige Definition der Klasse B einbinden
    #include "B.hpp"
    
    // Besser wäre hier eine Vorwärtsdeklaration
    class B;
    
    // Klasse, die mit B arbeitet
    class A
    {
        public:
            void Func1(B b);
            B Func2(const B& b);
        private:
            B* Var;
    };
    


  • Danke jetzt habs ich verstanden.
    Beim ersten war zu viel Fachchinesisch. 🙂
    Ich probier deins gleich mal.
    Es klappt nicht aber vielleicht schreibs ich auch nur an die falsche Stelle?
    Also das Spiel besteht ja noch aus viel mehr als meinem Ausschnitt und ich hab jetzt eure Vorschlage immer ganz oben hinter main gemacht.
    Ich zeigs nochmal

    //Spiel Zahlenraten
    //
    
    #include <iostream>
    #include <windows.h>
    #include <fstream>
    #include <iosfwd>
    
    using namespace std;
    

    So und ganz unten kommt dann erst meine Funktion aus dem ersten Beitrag.
    Wenn es so aussieht dann überspringt mein Programm immernoch die Highscore ausgaben, wenn ich <fstream> weglasse bekomme ich wieder zwölf Fehler.
    (Ich vermeide es die ganze Zeit das komplete Programm zu zeigen da es doch sehr lang ist. Vielleicht kennt ja jemand das Buch und versteht es dann.)



  • Die Vorwärtsdeklarationen kannst du lediglich brauchen, wenn du lediglich die Namen brauchst. (Also darst du z.B keine Objekte erstellen o.ä.)
    Vielleicht hilft dir auch dieser Beitrag hier:
    http://www.drakon.ch/?id=&offset=1&mobile=0&show_entry=77

    Wenn du bedenkst, dass in iosfwd eigentlich nur Vorwärtsdeklarationen sind, sollte das ganze klarer werden. Du benutzt ja bereits Code im Header (nehme ich an), also reicht eine Vorwärtsdeklaration nicht. (Weiteres siehe Blog Eintrag)

    Das mit dem überspringen der Ausgabe verstehe ich nicht ganz. Wie kommst du drauf, dass etwas übersprungen wird? - Bist du da mal mit dem Debugger durch? Rufst du die Funktion HighscoreAusgeben überhaupt auf?

    Am Header kann so etwas nicht liegen. Entweder der include ist da und es funktioniert (der Include) oder nicht und dann bekommst du Compile Fehler.



  • Rufst du denn die Funktion 'HighscoreAusgeben' auch in deinem Hauptprogramm auf?
    Wenn du die Funktion ganz am Ende stehen hast, benötigst du ebnfalls eine Vorwärtsdeklaration für deine Funktion, d.h.

    int HighscoreAusgeben (int Highscore);
    

    Ansonsten einfach mal den Debugger benutzen und Schritt für Schritt die Funktion durcharbeiten...



  • Ich habs gelöst viel rummel um eine einfache sache. 😃
    Ich hatte mich bei dem Funktionsnamen vertippt.
    Trotzdem danke!
    Schließlich hab ich was gelernt ich weiß jetzt was Vorwärtsdeklaration heißt.


Anmelden zum Antworten