<map> Key vorhanden?



  • Noch als Tip, damit du dir nicht jedes Mal nen Zahn abbrichst bei deinem wirklich nicht gerade unkomplexen map-Konstrukt:

    typedef std::map<string, map<string, map<string, map<string, map<string, string> > > > >  MyComplexMap;
    
    // anwenden:
    MyComplexMap::iterator iter = mapRealteile.begin();
    

    MyComplexMap ist dann einfach ein Alias-Name, den du überall einsetzen kannst. Nicht nur bei dem Iterator. Wird der Code auch übersichtlicher.



  • Eure beiden Posting haben mir wieder gut weitergeholfen! 🙂

    Ist ja recht logisch, warum man speziell zur map natürlich keine Quellcode-Beispiele findet! Das mit dem Typedef vereinfacht die Übersicht allerdings! Danke für den Link, ich werde da mal durchschauen.

    Ich will ja immernoch den Baum aufbauen. Ich habe das auch geschafft, nur ist die Performance viel zu schlecht. Daher mache ich jetzt die Operationen mit der map und übernehme dann die Struktur am Ende nurnoch in das CTreeCtrl, dürfte dann um einiges schneller sein. Ich hoffe mit den Infos komme ich zum Ende mit dem kleinen Programm :-).

    Auf jeden Fall wär ich ohne das Forum hier noch lange nicht so weit gewesen! 👍



  • Ich habe nun einiges zu den Iteratoren gelesen. Aber da sich die map ja im Vergleich zu den Listen unterscheidet, weiss ich immer noch nicht, wie ich eine map komplett auslesen kann. Weil first und second kennt mein iterator nicht (wie von templäd vorgeschlagen) und ich habe noch keine weitere Möglichkeit gefunden an den Key zu kommen. Im Prinzip sollte es doch sowas geben:

    Iterator anlegen
    Iterator der map zuordnen

    Iterator auf erstes Element setzen
    getKey, getValue

    Interator auf nächstes Element setzen
    getKey, getValue

    usw...



  • plizer schrieb:

    Ich habe nun einiges zu den Iteratoren gelesen. Aber da sich die map ja im Vergleich zu den Listen unterscheidet, weiss ich immer noch nicht, wie ich eine map komplett auslesen kann. Weil first und second kennt mein iterator nicht (wie von templäd vorgeschlagen) und ich habe noch keine weitere Möglichkeit gefunden an den Key zu kommen. Im Prinzip sollte es doch sowas geben:

    Klar kennt der Iterator first und second - zeig doch mal, was du gemacht hast.

    Iterator anlegen
    Iterator der map zuordnen

    Anlegen kannst du ihn durch eine einfache Definition map_typ::iterator pos; , explizit einer Map zuordnen mußt du ihn vorerst nicht (das passiert im nächsten Schritt automatisch)

    Iterator auf erstes Element setzen

    Den Iterator auf den Anfang liefert die Methode begin(): pos=meine_map.begin(); (damit hast du indirekt auch die Zuordnung zur Map hergestellt)

    getKey, getValue

    pos->first; liefert den Schlüssel, pos->second; den zugehörigen Wert.

    Interator auf nächstes Element setzen

    Das geht wie bei jedem anderen Iterator (und Zeiger) auch per ++pos;

    PS: Und um zu erkennen, ob du am Ende der Map bist, kannst du 'pos' vergleichen mit 'meine_map.end()'



  • Ja, so habe ich das eigentlich gemacht!
    Mal ein Beispiel:

    map<string, string> myMap;
    myMap.insert(make_pair("1", "Eins"));
    myMap.insert(make_pair("2", "Zwei"));
    myMap.insert(make_pair("3", "Drei"));
    
    map<string, string>::iterator myIter = myMap.begin();
    while(myIter != myMap.end()) {
    	cout << myIter.first;
    }
    

    Dann kommt die Fehlermeldung:

    error C2039: 'first' : Ist kein Element von 'iterator'

    Woran kann das liegen?



  • Hi,

    Iteratoren sind "Zeiger" auf Elemente. Dementsprechend musst Du mit "->" und nicht mit "." dereferenzieren.

    Gruß,

    Simon2.



  • oja, thx! 😕

    Aber mit "->" statt "." funktionierts so ja auch direkt nicht. Muss ich dann nicht mit "new" arbeiten?



  • Vor 10 Jahren bin ich mit C++ angefangen und hatte das mit den Zeigern auch soweit verstanden, aber nach 7 Jahren Java geht das wahrscheinlich nie wieder in mein Hirn rein :(.



  • Also eigentlich ist das doch gar nicht so anders ... nur musst Du eben "->" nehmen statt "." 😉

    Gruß,

    Simon2.



  • Ein new ist hier nicht nötig. Lediglich

    myIter->first;
    


  • Dann kommt allerdings die Fehlermeldung:

    d:\msstudio\vc98\include\utility(21) : error C2536: 'std::pair<char [2],char [5]>::first' : Angabe einer expliziten Initialisierung für Arrays nicht moeglich
    d:\msstudio\vc98\include\utility(25) : Siehe Deklaration von 'first'
    d:\msstudio\vc98\include\utility(21) : Bei der Kompilierung der Member-Funktion '__thiscall std::pair<char [2],char [5]>::std::pair<char [2],char [5]>(const char (&)[2],const char (&)[5])' der Klassenvorlage
    d:\msstudio\vc98\include\utility(21) : error C2536: 'std::pair<char [2],char [5]>::second' : Angabe einer expliziten Initialisierung für Arrays nicht moeglich
    d:\msstudio\vc98\include\utility(26) : Siehe Deklaration von 'second'
    d:\msstudio\vc98\include\utility(21) : Bei der Kompilierung der Member-Funktion '__thiscall std::pair<char [2],char [5]>::std::pair<char [2],char [5]>(const char (&)[2],const char (&)[5])' der Klassenvorlage

    Hier nochmal der Quelltext:

    map<string, string> myMap;
    	myMap.insert(make_pair("1", "Eins"));
    	myMap.insert(make_pair("2", "Zwei"));
    	myMap.insert(make_pair("3", "Drei"));
    
    	map<string, string>::iterator myIter = myMap.begin();
    	while(myIter != myMap.end()) {
    		cout << myIter->first;
    	}
    


  • Aber wahrscheinlich liegt es jetzt daran, dass cout das Zeug nicht ausgeben kann, weil mein uralt System wieder irgendwas zu meckern hat.



  • Boh, dieser verdammte std::string vom MSVC6! plizer, das hatten wir doch nun schon in fast jedem deiner Threads.

    Ich muß jetzt einfach mal ins blau raten, da ich kein MSVC6 hier habe:

    std::cout << myIter->first.c_str();
    


  • Das dachte ich auch mit dem c_str(), aber die Fehlermeldung bleibt. Hab schon gerade rumprobiert mit einigen Casts, aber irgendwie bringts keine Abhilfe. Es ist der gleiche Fehlercode, als ich eine map ohne make_pair erstellen wollte.

    Lange hab ich echt keine Lust mehr aufs MVC6 und werd hier mal was ändern müssen. Klar bin ich nicht gerade nen C++ Experte (sondern ein Anfänger) aber gerade da ist man mit solchen Meldungen (die ja kein anderer bekommt) total gekniffen... Ist ja ohne den Versionsunterschied schon schwer genug...



  • Also die Lösung ist folgende:

    #include <string>
    #include <map>
    #include <iostream>
    
    int main()
    {
        using namespace std;
        map<string, string> myMap;
        myMap.insert(make_pair(string("1"), string("Eins")));
        myMap.insert(make_pair(string("2"), string("Zwei")));
        myMap.insert(make_pair(string("3"), string("Drei")));
    
        map<string, string>::iterator myIter = myMap.begin();
        while(myIter != myMap.end()) {
            cout << myIter->first;
            ++myIter;
        }
    }
    

    Wobei ich die std:: Angabe vorziehe. Unter VC++ 6.0 wird man aber mit etlichen Warnungen aus den STL-Headern überhäuft.

    Unter VC++ 2005 läuft der Code ohne die explizite sting-Konvertierung beim make_pair auch auf höchter Warnstufe ohne Warnung und Fehler durch...

    Apropos: in deiner Version war eine Endlosschleife (End wird ohne durch-iterieren nie erreicht...);

    cu André



  • Was passiert denn, wenn du in der Zeile einfach nur myIter->first; schreibst. Macht zwar erstmal keinen Sinn, aber nur um den Fehler einzugrenzen.



  • Nachtrag: Warum verwendest du nicht einfach den freien VC++ 2005 (Express)... ;p



  • oder Code::Blocks?



  • Er kann kein MSVC8 benutzen! Hatten wir schon das Thema ausführlich in einem anderen Thread! Er entwickelt an einer alten kommerziellen Software, ein Umstieg ist nicht einfach so möglich.

    plizer! Probier mal http://www.stlport.org/ aus. Angeblich soll das eine ISO-konforme Std-Lib sein, die auch auf dem MSVC6 funktioniert.



  • Gut, selbst dann ist oben ein linkbarer Code... für make_pair ist halt vorher eine Typumwandlung der Einzeltypen nötig... Das Problem ist nur diese Stellen zu finden in all den Warnungen die man seitens des Compilers bekommt.


Anmelden zum Antworten