map: alle paare auslesen



  • Hallo zusammen. Habe ein Problem: ich benutze eine map um die Werte meiner Variablen zu speichern. Moechte nun den gesamten Inhalt der Map in einer Datei speichern. Leider klappt das nur mit dem ersten Paar, alle anderen fehlen. Kann mir jemand weiterhelfen wo ich das Problem suchen muss?

    {
    			Electric SysElectric;
    			std::vector<std::string> Content;
    			std::string::size_type found = std::string::npos;
    			std::map<std::string, std::string>  Values;
    				{
    				std::ifstream Config ("b777.cfg");
    				if(Config)
    				{
    					for (std::string ReadString; std::getline(Config, ReadString); )
    					Content.push_back(ReadString);
    					Config.close();
    
    					for(std::vector<std::string>::const_iterator itr = Content.begin();itr != Content.end(); ++itr)
    					{
    						found = (*itr).find("=");
    						if(found != std::string::npos)
    						{
    							Values[(*itr).substr(0, found)] = (*itr).substr(found+1, (*itr).length()-1);
    						}
    					}
    				}
    					else
    					{
    						MessageBox(NULL, L"File \"b777.cfg\" not found!", L"B777 Error", MB_OK | MB_ICONERROR);
    						exit (-1);
    					}
    				}
    				//Electric
    				{
    					const int i = SysElectric.GetApuState();
    					Values["ApuState"] = To_t<std::string>(i);
    				}
    				{
    					const int i = SysElectric.GetLeftGenDriveConnected();
    					Values["LeftGenDriveConnected"] = To_t<std::string>(i);
    				}
    				{
    					std::ofstream Config ("b777.cfg");
    					if(Config)
    					{
    						for(std::map<std::string, std::string>::const_iterator itr = Values.begin();itr != Values.end(); ++itr)
    						{
    							Config << (*itr).first << "=" << (*itr).second << std::endl;
    							Config.close();
    						}
    					}
    					else
    					{
    						MessageBox(NULL, L"Error writing File \"b777.cfg\"!", L"B777 Error", MB_OK | MB_ICONERROR);
    						exit (-1);
    					}
    				}
    			}
    


  • Map ist ja sehr beliebt in letzter Zeit, hui...

    Was mir sofort auffällt:

    a) Du hast unnötige Blöcke und eine selten komische Klammerung
    b) Statt (*iter).doSmth() macht man gewöhnlicherweise iter->doSmth()

    Das Rausschreiben funktioniert wohl deswegen nicht weil du das Config-File sofort nach dem du den ersten Wert reinschreibst schließt:

    for(...)
    {
        // Deins: Config << (*itr).first << "=" << (*itr).second << std::endl;
        // Meins:
        Config << iter->first << '=' << iter->second << endl;
        // Deins: Config.close(); // WTF?! Hier komplett fehl
    }
    // Meins, nach der for-schleife:
    Config.close();
    

    MfG SideWinder



  • Hallo SideWinde,

    die "unnoetigen Bloecke" sind nur wegen der Uebersichtlichkeit (fuer mich persoenlich).

    Aber Danke fuer den Hinweis was das schliessen der Datei angeht. Ist nicht das erste Mal das mir sowas passiert (leider ueberseh ich es immer wieder). Vielleicht doch zuviele Klammern 🙂

    Btw.: bin eben mal mit dem VC-Debugger die Schleife durchgegangen, tatsaechlich hat er vor dem "Config.close()" noch alle Zeilen. Mit ganz viel Glueck haette ich so vielleicht bemerkt das das File nach der ersten Zeile geschlossen wird.

    Vielen Dank nochmal. Hab uebrigens bei cppreference.com nachgeschaut ob ich vielleicht fuer sowas eine andere Funktion brauche. Konnte ich mir aber nicht so ganz vorstellen da ich diesen Weg (nicht den kompletten Code) aus einem Buch habe.

    Viele Gruesse
    Sven



  • schwudde schrieb:

    ...
    die "unnoetigen Bloecke" sind nur wegen der Uebersichtlichkeit (fuer mich persoenlich)....

    schwudde schrieb:

    ...Ist nicht das erste Mal das mir sowas passiert (leider ueberseh ich es immer wieder). Vielleicht doch zuviele Klammern :-)...

    Definitiv !

    Ich habe mal ein wenig "durchforstet":

    {
       Electric SysElectric;
       std::vector<std::string> Content;
       std::string::size_type found = std::string::npos;
       std::map<std::string, std::string>  Values;
       std::ifstream ConfigIn ("b777.cfg");
       if(!ConfigIn) {
       	MessageBox(NULL, L"File \"b777.cfg\" not found!", L"B777 Error", MB_OK | MB_ICONERROR);
       	exit (-1); // wäre return nicht besser ? Dann wird wenigstens noch "aufgeräumt"
       }
    
    	for (std::string ReadString; std::getline(ConfigIn, ReadString); ) Content.push_back(ReadString);
    
    	for(std::vector<std::string>::const_iterator itr = Content.begin();itr != Content.end(); ++itr) {
    		found = itr->find("=");
    		if(found != std::string::npos) Values[itr->substr(0, found)] = itr->substr(found+1, itr->length()-1);
       }
       //Electric
       Values["ApuState"] = To_t<std::string>(SysElectric.GetApuState());
       Values["LeftGenDriveConnected"] = To_t<std::string>(SysElectric.GetLeftGenDriveConnected());
       ConfigIn.close();
    
       std::ofstream ConfigOut ("b777.cfg");
       if(!ConfigOut) {
    		MessageBox(NULL, L"Error writing File \"b777.cfg\"!", L"B777 Error", MB_OK | MB_ICONERROR);
    		exit (-1); // wäre return nicht besser ? Dann wird wenigstens noch "aufgeräumt"
    	}
    
    	for(std::map<std::string, std::string>::const_iterator itr = Values.begin();itr != Values.end(); ++itr)
    	   Config << itr->first << "=" << itr->second << std::endl;
    
       return 0;
    }
    

    Ist natürlich viel Geschmacksache, aber ich find's übersichtlicher so.
    Man kann sich noch überlegen, nur ein fstream Config; zu verwenden und es erst zum Lesen, zu Schließen und dann zum Schreiben zu öffnen....

    Gruß,

    Simon2.



  • Wenn du bereits den Debugger einsetzt bist du auf jeden Fall am richtigen Weg 👍

    MfG SideWinder


Anmelden zum Antworten