Komische Endloschleife bei for( i=0; i < x; ++i )



  • Ich habe folgendes Problem:

    Wenn die nachfolgende Funktion mit

    exploded = explode( "\n=", "-1" );
    

    aufrufe, dann macht die eine Endloschlefe im FOR Teil, ich kann leider nichts entdecken, da i die Länge von "-1" erreicht (also 2), aber sobald i = 2 ist, wird, irgendwie, irgendwo, i auf 0 zurückgesetzt.

    Hat jemand Rat? Hab' ich Tomaten auf den Augen?

    Vielen Dank im Voraus

    map <int,string> explode( const string& separator, const string& data )
         {
         map <int,string> values;
         int i = 0, j = 0, result;
         string test;
    
         if ( !separator.empty() and !data.empty() )
            {
            values[0]="";
            int stop = data.length();
            for ( i=0; i <= stop; ++i )
                {
                result = separator.find(data[i]);
                if ( result > -1 )
                   {
                   ++j;
                   }
                else
                   {
                   if ( data[i] != '\0' )
                      {
                      values[j] += data[i];
                      }
                   }
                }
            }
         ++j;
         return values;
         }
    


  • Ein bisschen komisch ist das ++j plaziert. hab jetz den fehler nicht wirklich gefunden, drum das:
    <pre>Die Antwort ist in der Annahme, dass du einen String der durch mehrere Seperator getrennt ist in eine map einlesen willst, entstanden. wenn dem nicht so ist, dann vergiss es einfach :)</pre>
    Hab das mal bisschen leselicher gemacht, und paar sachen ausgebessert. sehe ich das richtig, dass du einen string nach einem seperator zerlegst, und die der reihe nach in eine map haust. wieso keinen vektor/list, wenn du sowieso nur die zahl hochzaehlst?
    *untested*

    map <int,string> explode( const string& separator, const string& data ) 
    { 
        map <int,string> values; // besser eine liste, anscheinend numerierst du je einfach aufsteigend
        // string test; wozu den?
        // "and" gibts eigentlich in c++ nicht
        if (separator.empty() || data.empty()) 
            return values;     // values[0]="";  das brauchts eigentlich nicht
        int counter = 0;
        while (true)
        {
            std::string::size_type pos;
            pos = data.find(seperator, 0);
            if (pos == std::string::npos) // fertig, alle seperator abgearbeitet
            {
                values[counter++] = data;
                break; // raus aus der schleife, wir sind ferig
            }
            values[counter++] = data.substr(0, (pos - 1)); // in die map schubsen
            data = data.substr((pos + seperator.length()-1)); // Zeichen bis einschlieslich Seperator aus data löschen
        }
        return values; 
    }
    


  • Hi Korbinian, erstmals vielen Dank für die prompte Antwort.

    Wie schon im Titel vermerkt sind das letzte ++j und der string test überflüssig, ich habe auch desweiteren bemerkt, dass das AND eigentlich ein OR sein sollte. Die Funktion habe ich vor ca. einem Jahr gebastelt und mittlerweile ist das Programm ca. 6'000 Zeilen "schwer", somit geht manches "verloren".

    Den Sinn der Funktion hast du korrekt erkannt, man kann mehrere Separatoren angeben um einen string aufzusplittern.

    Die map brauche ich, da ich manchmal, eigentlich fast immer, Zugriff über über mehrere Indexe gleichzeitig benötige, für Vergleiche und so weiter.

    Deine Funktion, auf den ersten Blick, scheint "heavier" sein. Ich meine langsamer, oder irre ich mich? Da diese explode Funktion viel gebraucht wird... 😉

    Was mich laust, ist: wie zum Affen kann es sein dass eine FOR Scheife sich endlos fortsetzt obwohl den Endwert erreicht wird? Wie kann das möglich sein?



  • Wenn eine Variable plötzlich einen Wert hat, den sie nicht haben dürfte, ist das immer ein Zeichen dafür, daß in einer anderen Variablen eine Bereichsüberschreitung auftritt.

    Hier ist dies wohl bei:

    for ( i=0; i <= stop; ++i )
    

    "stop" ist gleich Data.Length(), also die Anzahl der Zeichen in "data". "data[stop]" ist aber dann ein Byte zu weit, da "data" von "data[0]" bis "data[data.length()-1] geht. Ein "std::string" ist ja nicht Null-terminiert.

    Also:

    for ( i=0; i < stop; ++i )
    

    Hmmm....hoffe, ich habe mich verständlich ausgedrückt...



  • Das hatte ich auch gedacht, aber es passiert genau dasselbe, die Schleife wird endlos auch mit i < stop.

    Es muss wohl was anderes sein.



  • // "and" gibts eigentlich in c++ nicht

    Eigentlich schon.

    siehe <ciso646>



  • 1.4.2.2 Header <iso646.h> [diff.header.iso646.h]

    1 The tokens and, and_eq, bitand, bitor, compl, not_eq, not, or, or_eq,
    xor, and xor_eq are keywords in this International Standard
    (_lex.key_). They do not appear as macro names defined in <ciso646>.


Anmelden zum Antworten