Was für die ::Hyper.Experten...Am verzweifeln :-(



  • Hi,

    Wie kann man den einen Strng 'zerschießen' ? ...Hab ich das irg wo gemacht (siehe erstes CodePosting) ?

    und Danke für deine Antwort!


  • Mod

    du könntest im destruktor einen breakpoint setzen und dir dort den zustand des objekts anzeigen lassen. das wäre dann unmittelbar vor der absturzstelle. aus dem zustand des objekts kann man dann möglicherweise auf die fehlerursache schließen.



  • this->IPlayback::dspDSetPos.ulBegin = static_cast<unsigned long>(fsCfgFile.tellp());
    

    Bist du sicher, daß so etwas durch den Compiler kommt? Du hast dort ein paar struct's definiert, aber ich sehe nirgends ein Objekt von Typ "IPlayBack". (und selbst wenn diese Zeile durch den Compiler kommt, sieht sie extrem ungesund aus)


  • Mod

    dass der compiler das annimmt, ist allerdings verwunderlich. IPlayback::dspDSetPos ist kein member von CAppData. es stellt sich sowieso die frage, welche mögliche bedeutung das haben sollte.



  • camper schrieb:

    du könntest im destruktor einen breakpoint setzen und dir dort den zustand des objekts anzeigen lassen.

    Hab ich, mit diesem (interessanten) Ergebnis:

    string _strCfgPath = ""; /* oho?, nix? */
    string _strIdxPath = "C:\\idxPos.gfx"; /* ok! */
    

    _______________________________________________________

    CStoll schrieb:

    aber ich sehe nirgends ein Objekt von Typ "IPlayBack"

    Das müsste doch von der Deklaration verdeckt werden oder nicht ?

    _______________________________________________________

    camper schrieb:

    dass der compiler das annimmt, ist allerdings verwunderlich. IPlayback::dspDSetPos ist kein member von CAppData.

    Wieso? IPlayback::dspDSetPos ist doch ein member von CAppData...siehe hier:

    struct IPlayback /* << Wiedergabeoptionen */
            {
                bool         fPaused;        /* Wiedergabe pausiert ?        */
                bool         fInit;            /* Mediendatei geladen ?        */
                bool         fLocalMute;    /* lokale Lautstärke gemutet ?    */
                bool         fGlobalMute;    /* globale Lautstärke gemutet ?    */
                unsigned int uiLocalVol;    /* lokaler Lautstärke Wert        */
                unsigned int uiGlobalVol;    /* globaler Lautstärke Wert        */
                bool         fRepeat;        /* Wiederholen (Repeat-Mode) ?    */
                ERepeatModes rpRepMode;        /* Wiederholungsmodus (ENUM)    */
                /* -------
                Sicherung: fLocalMute, uiLocalVol, fRepeat, rpRepMode
                ----------*/
                bool        fSaved;            /* bereits in Datei gespeichert    */
                SDataSetPos    dspDSetPos;        /* VOILA! ;)    */
            };
    

    Danke nochmal/schonmal 😉 für eure Hilfe, echt nett 👍



  • Expertensucher schrieb:

    Wieso? IPlayback::dspDSetPos ist doch ein member von CAppData...siehe hier:

    Nein, dspDSetPos ist ein Member von IPlayback, und IPlayback ist garkein Objekt sondern ein Typ. Dieser Typ existiert im Scope der Klasse CAppData (Du könntest mit CAppData::IPlayback myPlayback; ein Objekt davon erzeugen). Einen Member vom Typ IPlayback gibt es jedoch garnicht.



  • Hi,
    Könntest du mir das:

    LordJaxom schrieb:

    (Du könntest mit CAppData::IPlayback myPlayback; ein Objekt davon erzeugen)

    mal daran:

    class CAppData
    {
        /* -----------------------------------------------------------------------------*/
        private: /* -Declarations                                                       */
        /* -----------------------------------------------------------------------------*/
            struct IPlayback /* << Wiedergabeoptionen */
            {
                bool         fPaused;        /* Wiedergabe pausiert ?        */
                bool         fInit;            /* Mediendatei geladen ?        */
                bool         fLocalMute;    /* lokale Lautstärke gemutet ?    */
                bool         fGlobalMute;    /* globale Lautstärke gemutet ?    */
                unsigned int uiLocalVol;    /* lokaler Lautstärke Wert        */
                unsigned int uiGlobalVol;    /* globaler Lautstärke Wert        */
                bool         fRepeat;        /* Wiederholen (Repeat-Mode) ?    */
                ERepeatModes rpRepMode;        /* Wiederholungsmodus (ENUM)    */
                /* -------
                Sicherung: fLocalMute, uiLocalVol, fRepeat, rpRepMode
                ----------*/
                bool        fSaved;            /* bereits in Datei gespeichert    */
                SDataSetPos    dspDSetPos;        /* Position dieses Datensatzes    */
            };
    
            struct IOptions /* << Programmoptionen */
            {
                struct IStartup /* << Programmstart-Einstellungen */
                {
                    bool        fAutoStart;    /* beim Systemstart laden ?                */
                    bool        fStartMin;    /* Programm miniert starten ?            */
                    string        strKeyName;    /* Name des Registry-Eintrags            */
                    string        strKeyPath;    /* Registry-Wert (Pfad) von strKeyName    */
                    /* -------
                    Sicherung: Alle
                    ----------*/
                    bool        fSaved;        /* bereits in Datei gespeichert            */
                    SDataSetPos    dspDSetPos;    /* Position dieses Datensatzes            */
                };
                // [> TODO: Weitere Optionen implementieren
            };
    
            struct IInterface /* << Fenstereinstellungen */
            {
                bool fPrstPaused;    /* Trackinformationscontrol pausiert ?    */
                bool fTopmostWnd;    /* Hauptfenster immer im Vordergrund ?    */
                /* -------
                Sicherung: Alle
                ----------*/
                bool        fSaved;        /* bereits in Datei gespeichert    */
                SDataSetPos    dspDSetPos;    /* Position dieses Datensatzes    */
            };
    
            string    _strCfgPath;        /* Dateipfad zur Konfigurationsdatei    */
            string    _strIdxPath;        /* Dateipfad zur Indexdatei                */
            bool    _fDataSetsSaved;    /* Alle Datensätze gespeichert ?        */
            bool    _fCfgFileCreated;    /* Konfigurationsdatei bereits erstellt    */
            bool    _fIdxFileCreated;    /* Indexdatei bereits erstellt            */
    
            // [> TODO: Weiteres...
        /* -----------------------------------------------------------------------------*/
        public: /* -Declarations                                                        */
        /* -----------------------------------------------------------------------------*/
    

    zeigen ?, bitte *schöne-Augen-mach* ^^

    Weiß nämlich nicht genau wie ich das deklarieren soll 😕


  • Mod

    ein objekt definierst du so:

    T name;
    

    wobei T irgendein typ ist und name evtl. noch mit deklaratoren ([] * () &) dekoriert wird (das ergebnis muss ein vollständiger typ sein). es ist dabei möglich, den typ erst in der variablendefinition zu definieren, also z.B.:

    struct T { /* ... */ } name;
    

    tatsächlich ist die übliche form der klassendefinition nichts weiter als eine variablendefinition, die keine variable definiert:

    struct T { /* ... */ };
    

    umkehrt kannst du z.B. in diesem fall auch darauf verzichten, der klasse einen namen zu geben (vorausgesetzt, du brauchst ihn nicht noch einmal):

    struct { /* ... */ } name;
    

    hier ist der typ selbst unbenannt.

    jetzt sollte auch klar sein, warum man die klassendefinition immer mit semikolon abschließen muss, während das bei funktionsdefinitionen unnötig ist.

    schau auch mal hier rein:http://www.c-plusplus.net/forum/viewtopic-var-t-is-150636.html



  • Hi nochmal....hab mal ne Frage am Rande:...Geht das denn ? (wg Speicherreservierung):

    fsCfgFile.write(strFTBeginCfgFile.c_str(), strFTBeginCfgFile.length());
    

    ? thx schomah^^



  • Das sollte gehen. Ich hoffe, du speicherst auch die Länge des Strings mit ab, sonst wird das mit dem Einlesen schwierig.



  • oh, jo stimmt...muss ich noch :p



  • Wow, erstmal an alle ein riesen Dankeschön... ES FUNKTIONIERT!!! 😋 🙂 😃

    Hab die Structs jetzt so bspw definiert:

    struct IPlayback /* << Wiedergabeoptionen */
            {
                bool         fPaused;        /* Wiedergabe pausiert ?        */
                bool         fInit;            /* Mediendatei geladen ?        */
                bool         fLocalMute;    /* lokale Lautstärke gemutet ?    */
                bool         fGlobalMute;    /* globale Lautstärke gemutet ?    */
                unsigned int uiLocalVol;    /* lokaler Lautstärke Wert        */
                unsigned int uiGlobalVol;    /* globaler Lautstärke Wert        */
                bool         fRepeat;        /* Wiederholen (Repeat-Mode) ?    */
                ERepeatModes rpRepMode;        /* Wiederholungsmodus (ENUM)    */
                /* -------
                Sicherung: fLocalMute, uiLocalVol, fRepeat, rpRepMode
                ----------*/
                bool        fSaved;            /* bereits in Datei gespeichert    */
                SDataSetPos    dspDSetPos;        /* Position dieses Datensatzes    */
            } IPlaybackData;
    // Zugriff:
    this->IPlaybackData.fPaused = true;
    

    ...wunderbar...nur:

    Hab aber noch n kleines ziemlich nerviges Problem 😡 ...:

    Ich schreib grad an einer Methode, die prüft, ob bestimmte 'TAGS' also abstrakt strings in der Datei vorkommen... (um kurz gesagt zu prüfen, ob es sich um eine von mir erstellte ConfigDatei handelt). Dazu folgende Methode:

    bool CAppData::IsValidIndexFile(const string& strIdxSrc)
    {
    	if(strIdxSrc.c_str() == NULL)
    		return (false);
    
    	unsigned long ulFileBytes = this->GetFileSize(strIdxSrc);
    	if(!ulFileBytes)
    		return (false);
    	fstream	fsIdxFile(this->_strIdxPath.c_str(), ios::in | ios::binary);
    	if(!fsIdxFile.is_open())
    		return (false);
    
    	PCSTR pszFileBuffer = new CSTR[ulFileBytes + 1];
    	memset(pszFileBuffer, 0, ulFileBytes + 1); // HIER NOCHMAL NE FRAGE: is das wohl nötig ?
    
    /*
    PCSTR ist char* oder wchar_t* je nachdem (->UNICODE)
    -------------------------------------------
    Die Prüfstrings(TAGS) sind so deklariert:
    extern const PCSTR cszFTBeginIdxFile;
    extern const PCSTR cszFTEndIdxFile;
    extern const PCSTR cszFTIdxBlockBegin;
    extern const PCSTR cszFTIdxBlockEnd;
    */
    
    	fsIdxFile.read(pszFileBuffer, ulFileBytes);
    
    	cout << pszFileBuffer << endl << endl; // 1:->>>>KAWUMM....Hier gibt er nur ca. die ersten 30 Zeichen aus ?! ARRG!
    
    	if(!fsIdxFile.fail())
    	{
    		string strSearch(pszFileBuffer);
    		if(strSearch.find(cszFTBeginIdxFile) == 0) // 2:->>>>noch true
    		{
    			if(strSearch.find(cszFTEndIdxFile) == (ulFileBytes - strlen(cszFTEndIdxFile))) // 3:->>>>schon false; Grund, siehe 1:
    			{
    				// usw., weitere TAGS prüfen...
    				return (true);
    			}
    			else
    				return (false);
    		}
    		else
    			return (false);
    	}
    	return (false);
    }
    

    Seht ihr vllt. n Fehler oder was 'unschönes'/unsicheres ?

    Achja ...der Return-Wert der (von mir geschriebenen)Methode GetFileSize() stimmt. 👍 Den hab ich geprüft (230 (Bytes), wenn wichtig ist) 💡

    Wenn ihr wollt, kann ich euch noch den (vom Windows-Texteditor angezeigten) Inhalt der Zieldatei geben, und/oder das, was leider nur davon ausgegeben wird (also via std::cout)...müsst ihr sagen 😉

    Ich hoffe ich nerve euch nicht...und mein Post war kein Schmand (so nach dem Motto: Hälfe vergessen, nicht lesbar, ungenaue Frage etc., ... 😃 )

    🙂 DAnKe NocHmaL/ScHoNmaL 🙂


  • Mod

    Expertensucher schrieb:

    PCSTR pszFileBuffer = new CSTR[ulFileBytes + 1];
    	memset(pszFileBuffer, 0, ulFileBytes + 1); // HIER NOCHMAL NE FRAGE: is das wohl nötig ?
    

    wenn CSTR sowohl char als auch wchar_t sein kann, müsste das memset nat. angepasst sein (weil memset selbst stets mit char arrays arbeitet). z.b.

    PCSTR pszFileBuffer = new CSTR[ulFileBytes + 1];
    memset(pszFileBuffer, 0, (ulFileBytes + 1)*sizeof(CSTR));
    

    eleganter ist aber, den new-operator dafür einzusetzen:

    PCSTR pszFileBuffer = new CSTR[ulFileBytes + 1][b]()[/b];
    

    da CSTR ein POD ist, führt das klammerpaar dazu, dass das array value-initialisiert wird - also mit dem wert 0 in diesem falle (wenn die array-elemente keine PODs wären, machte es keinen unterschied - die elemente würden dann stets durch den default-konstruktor konstruiert werden). evtl. solltest du mal die eingangsdaten zeigen.



  • camper schrieb:

    evtl. solltest du mal die eingangsdaten zeigen

    jop, kein Problem...hier ist die Quelldatei, die ich auslese:
    (ausgelesen mit Texteditor: Zeichen werden also tw. falsch interpretiert, da im Binärmodus geschrieben)
    Quelldatei:

    DEF_IDXPOS_GFX#FILE_VERSION#÷  #DATAPOS_BLOCK_BEGIN##IPLB_BLOCK_BEGIN#E   %O   #IPLB_BLOCK_END##IITF_BLOCK_BEGIN#q   %s   #IITF_BLOCK_END##ISTP_BLOCK_BEGIN#•   %—   #ISTP_BLOCK_END##DATAPOS_BLOCK_END#IDXPOS_GFX_ENDDEF
    

    Hier die Ausgabe in der DosBox (via std::cout):

    DEF_IDXPOS_GFX#FILE_VERSION#,[Herzchen]
    

    [Herzchen] ist im warsten Sinne des Wortes ein kleines Herz...was ich hier leider nicht einfügen konnte 😃

    Emm @camper: Noch mal Frage: Was ist (ein) POD ? 🤡

    camper schrieb:

    eleganter ist aber, den new-operator dafür einzusetzen:

    Jo hast Recht! ...Das sieht echt schöner aus... 👍 Gute Idee! Danke! 😉

    _______________________________________________________________

    Ich hab noch was total komisches raus gefunden...der folgende Code funktioniert und gibt den Inhalt vollständig auf die Konsole aus:

    fsIdxFile.seekg(0L); // nochmal annen Anfang
        for(char ch; fsIdxFile.get(ch) && cout.put(ch); ); // Ausgabe
    

    ...Ich versteh das nicht 😕 😞 🙄


  • Mod

    Expertensucher schrieb:

    Ich hab noch was total komisches raus gefunden...der folgende Code funktioniert und gibt den Inhalt vollständig auf die Konsole aus:

    fsIdxFile.seekg(0L); // nochmal annen Anfang
        for(char ch; fsIdxFile.get(ch) && cout.put(ch); ); // Ausgabe
    

    ...Ich versteh das nicht 😕 😞 🙄

    da die datei im binärmodus beschieben wurde, enthält sie offenbar auch \0 zeichen eingebettet. das ist aber gleichzeitig der terminator für C-strings. du könntest das ganze vor der ausgabe in einen std::string verwandeln (der eingebettete \0 enthalten darf) - dabei aber aufpassen, den fehler nicht zu wiederholen:

    cout << string(pszFileBuffer,ulFileBytes);
    

    auf das +1 kannst du bei der reservierung dann verzichten - da der puffer ohnehin nicht als c-style string dienen kann. dieses +1 dient ja gerade dazu, noch einen terminator am ende zu haben.

    Emm @camper: Noch mal Frage: Was ist (ein) POD ?

    POD steht für "plain old data" (das ist ein offizieller begriff des standards). gemeint sind damit datentypen, die sich wie datentypen in C verhalten (nicht alle - wie z.b. memberpointer - existieren auch in C). die exakte definition is rekusiv:
    - alle built-ins und enums sind PODs
    - arrays sind PODs, wenn ihre elemente PODs sind
    - klassen sind PODs, wenn sie
    -- weder selbstdefinierte Konstruktoren noch selbstdefinierten destruktor haben, und
    -- keine virtuellen funktionen haben, und
    -- nicht von einer basisklasse erben, und
    -- keine protected oder private elemente haben, und
    -- alle member PODs sind, und
    -- wahrscheinlich noch etwas, das ich gerade vergessen habe
    das prinzip müsste klar werden



  • Hi camper...erstmal danke für deine Bemühungen/Ausführungen bzgl. POD^^ ... 👍

    Also ich hab das:

    camper schrieb:

    cout << string(pszFileBuffer,ulFileBytes);

    einfach mal ausprobiert...Aber das hat nix gebracht...gleiches (unvollständiges) Ergebnis wie zuvor mit "cout << pszFileBuffer << endl << endl;"

    camper schrieb:

    enthält sie offenbar auch \0 zeichen eingebettet

    Ja muss sie ja...naja ich schreibe die Datei so:

    // TAG:		DEF_IDXPOS_GFX
    	fsIdxFile.write(cszFTBeginIdxFile, strlen(cszFTBeginIdxFile)); // <- Dateianfangs-Tag schreiben
    	// TAG:		#FILE_VERSION#
    	fsIdxFile.write(cszFTFileVersion, strlen(cszFTFileVersion)); // <- Dateiversion-Tag schreiben
    	// VALUE:	lFileVer
    	fsIdxFile.write(reinterpret_cast<char*>(&lFileVer), sizeof(long)); // <- Dateiversion schreiben
    	// TAG:		#DATAPOS_BLOCK_BEGIN#
    	fsIdxFile.write(cszFTIdxBlockBegin, strlen(cszFTIdxBlockBegin)); // <- Datenpositionsblockanfang-Tag schreiben
    
    	// TAG:		#IPLB_BLOCK_BEGIN#
    	fsIdxFile.write(cszFTPlaybackBegin, strlen(cszFTPlaybackBegin)); // <- Playback-Blockanfang-Tag schreiben
    	// VALUE:	IPlaybackCfg.dspDSetPos.ulBegin
    	fsIdxFile.write(reinterpret_cast<char*>(&this->IPlaybackCfg.dspDSetPos.ulBegin), sizeof(unsigned long));
    	// TAG:		%
    	fsIdxFile.write(reinterpret_cast<const char*>(&chSeparator), sizeof(char)); // <- Wert-Trennzeichen schreiben
    	// VALUE:	IPlaybackCfg.dspDSetPos.ulEnd
    	fsIdxFile.write(reinterpret_cast<char*>(&this->IPlaybackCfg.dspDSetPos.ulEnd), sizeof(unsigned long));
    	// TAG:		#IPLB_BLOCK_END#
    	fsIdxFile.write(cszFTPlaybackEnd, strlen(cszFTPlaybackEnd)); // <- Playback-Blockend-Tag schreiben
    
    	// TAG:		#IITF_BLOCK_BEGIN#
    	fsIdxFile.write(cszFTInterfaceBegin, strlen(cszFTInterfaceBegin)); // <- Interface-Blockanfang-Tag schreiben
    	// VALUE:	IInterfaceCfg.dspDSetPos.ulBegin
    	fsIdxFile.write(reinterpret_cast<char*>(&this->IInterfaceCfg.dspDSetPos.ulBegin), sizeof(unsigned long));
    	// TAG:		%
    	fsIdxFile.write(reinterpret_cast<const char*>(&chSeparator), sizeof(char)); // <- Wert-Trennzeichen schreiben
    	// VALUE:	IInterfaceCfg.dspDSetPos.ulEnd
    	fsIdxFile.write(reinterpret_cast<char*>(&this->IInterfaceCfg.dspDSetPos.ulEnd), sizeof(unsigned long));
    	// TAG:		#IITF_BLOCK_END#
    	fsIdxFile.write(cszFTInterfaceEnd, strlen(cszFTInterfaceEnd)); // <- Interface-Blockend-Tag schreiben
    
    	// TAG:		#ISTP_BLOCK_BEGIN#
    	fsIdxFile.write(cszFTStartupBegin, strlen(cszFTStartupBegin));
    	// VALUE:	IOptionsCfg.IStartupCfg.dspDSetPos.ulBegin
    	fsIdxFile.write(reinterpret_cast<char*>(&this->IOptionsCfg.IStartupCfg.dspDSetPos.ulBegin), sizeof(unsigned long));
    	// TAG:		%
    	fsIdxFile.write(reinterpret_cast<const char*>(&chSeparator), sizeof(char)); // <- Wert-Trennzeichen schreiben
    	// VALUE:	IOptionsCfg.IStartupCfg.dspDSetPos.ulEnd
    	fsIdxFile.write(reinterpret_cast<char*>(&this->IOptionsCfg.IStartupCfg.dspDSetPos.ulEnd), sizeof(unsigned long));
    	// TAG:		]%[
    	fsIdxFile.write(cszStrLengthSep, strlen(cszStrLengthSep)); // <- Informations-Trennzeichen schreiben
    	// VALUE:	IOptionsCfg.IStartupCfg.uiLenKeyName
    	fsIdxFile.write(reinterpret_cast<char*>(&this->IOptionsCfg.IStartupCfg.uiLenKeyName), sizeof(unsigned int));
    	// TAG:		%
    	fsIdxFile.write(reinterpret_cast<const char*>(&chSeparator), sizeof(char)); // <- Wert-Trennzeichen schreiben
    	// VALUE:	IOptionsCfg.IStartupCfg.uiLenKeyPath
    	fsIdxFile.write(reinterpret_cast<char*>(&this->IOptionsCfg.IStartupCfg.uiLenKeyPath), sizeof(unsigned int));
    	// TAG:		#ISTP_BLOCK_END#
    	fsIdxFile.write(cszFTStartupEnd, strlen(cszFTStartupEnd));
    
    	// TAG:		#DATAPOS_BLOCK_END#
    	fsIdxFile.write(cszFTIdxBlockEnd, strlen(cszFTIdxBlockEnd));
    	// TAG:		IDXPOS_GFX_ENDDEF
    	fsIdxFile.write(cszFTEndIdxFile, strlen(cszFTEndIdxFile));
    

    ...Da muss es doch ne Lösung zu geben 😞



  • Hmm hab noch mal ne Frage wie kann ich denn das:

    fsIdxFile.seekg(0L); // nochmal annen Anfang
        for(char ch; fsIdxFile.get(ch) && cout.put(ch); ); // Ausgabe
    

    statt auf cout innen std::string umleiten ?...Also das 'ch' sozusagen immer an den String anhängen... ?
    vllt. klappt das ja... 💡 ...also vollständig OHNE C-Strings, nur mit ner einfachen char-Variable 👍

    Boah is das ne Kagge...das muss doch irg wie funktionieren...*grummel*



  • std::cout <<  std::string("Hel\0lo", 6) << std::endl;
    

    funzt bei mir



  • tja schrieb:

    std::cout <<  std::string("Hel\0lo", 6) << std::endl;
    

    funzt bei mir

    Oha...was gibt er denn bei dir da aus...bei mir steht da nur "Hel" ...mehr nicht 😕 😕 😕 😕 😕



  • Hab noch was ausprobiert:

    // ...
    	string strLoad;
    	for(char chRead; fsIdxFile.get(chRead); )
    		strLoad += chRead;
    	cout << strLoad;
    // ...
    

    und das funktioniert auch nicht ... (gleiche unvollständige Ausgabe)
    Kann echt nicht wahr sein 😡 😞 😡 😞


Anmelden zum Antworten