Frage

Ich habe eine harte Zeit mit std :: string :: Iteratoren in C ++. Dieser Code kompiliert fein (noch nicht korrekte Ausgabe bekommen, aber das ist mein Fehler: TODO, fix-Algorithmus) in Dev-C ++, und ich weiß nicht Laufzeitfehler erhalten. Der Fehler ist mit Visual Studio Express 2008 C ++, wo ich erhalte eine Fehlermeldung zeigt auf : "Expression: string Iterator nicht dereferencable". Und die Punkte 112 der Datei Zeile

Meine Debuggen sagt mir, ich könnte zu dereferenzieren vorbei am Ende des Satzes Eingabe versuchen, aber ich kann nicht sehen, wo. Kann jemand etwas Licht?

std::string wordWrap(std::string sentence, int width)
{    
    std::string::iterator it = sentence.begin();

    //remember how long next word is
    int nextWordLength = 0;
    int distanceFromWidth = width;

    while (it < sentence.end())
    {
       while (*it != ' ' && it != sentence.end())
       {
          nextWordLength++;
          distanceFromWidth--;
          it++;
       }

       if (nextWordLength > distanceFromWidth)
       {
          *it = '\n';
          distanceFromWidth = width;
          nextWordLength = 0;
       }

       //skip the space
       it++;

   }

   return sentence;    
}
War es hilfreich?

Lösung

!

Erstens Verwendung operator = () auf Iteratoren nicht Operator <():

while (it != sentence.end())

Zum anderen ist dies nach hinten: while (*it != ' ' && it != sentence.end())

Sie tun etwas mit dem Iterator, als ob der Iterator gültig ist. Vielmehr sollten Sie prüfen, ob es gültig ist zuerst:

while (it != sentence.end() && *it != ' ')

Drittens sollten Sie ++ Iterator über Iterator ++ verwenden, obwohl dies nicht auf Ihre Krachen verwandt ist.


Viertens, ein Hauptproblem ist hier:

*it = '\n';

Aufgrund der vorangegangenen Überprüfung, while (it != sentence.end(), dann ist es möglich, dass der Iterator dereferenzieren zu erreichen, während am Ende zu sein. Ein Update wäre, dies zu tun:

if (it != sentence.end() && nextWordLength > distanceFromWidth)

So, jetzt, wenn Sie das Ende erreicht haben, Sie stoppen.


Nach der letzten Ausgabe Festsetzung jetzt das einzige Problem ist folgende:

//skip the space
++it;

Dies setzt voraus, dass das Zeichen, das Sie das Überspringen in der Tat ist ein Raum. Aber was ist mit dem Ende der Schnur? Führen Sie diese Funktion mit dieser Zeichenfolge:

"a test string " // <- space at end

Und es wird gelingen; überspringt er den Raum, den Iterator auf end() setzen, die Schleife beendet und Erfolg.

Doch ohne den Raum wird es zum Absturz, weil Sie das Ende erreicht haben, und über das Ende sind übersprungen wird. Um dies zu beheben, fügen Sie einen Scheck:

//skip the space
if (it != sentence.end())
{
    ++it;
}

in diesem letzten Code Resultierende:

std::string wordWrap(std::string sentence, int width)
{    
    std::string::iterator it = sentence.begin();

    //remember how long next word is
    int nextWordLength = 0;
    int distanceFromWidth = width;

    while (it != sentence.end())
    {
        while (it != sentence.end() && *it != ' ')
        {
            nextWordLength++;
            distanceFromWidth--;
            ++it;
        }

        if (it != sentence.end() && nextWordLength > distanceFromWidth)
        {
            *it = '\n';
            distanceFromWidth = width;
            nextWordLength = 0;
        }

        //skip the space
        if (it != sentence.end())
        {
            ++it;
        }

    }

    return sentence;    
}

Sie können feststellen, dies scheint, wie es eine Menge redundanter Kontrollen hat. Dies kann behoben werden:

std::string wordWrap(std::string sentence, int width)
{    
    std::string::iterator it = sentence.begin();

    //remember how long next word is
    int nextWordLength = 0;
    int distanceFromWidth = width;

    while (it != sentence.end())
    {
        while (*it != ' ')
        {
            nextWordLength++;
            distanceFromWidth--;

            ++it;

            // check if done
            if (it == sentence.end())
            {
                return sentence;
            }
        }

        if (nextWordLength > distanceFromWidth)
        {
            *it = '\n';
            distanceFromWidth = width;
            nextWordLength = 0;
        }

        //skip the space
        ++it;
    }

    return sentence;    
}

Hoffentlich! Hilft

Andere Tipps

while (*it != ' ' && it != sentence.end())

Änderungen

while (it != sentence.end() && *it != ' ')

, so dass die zweite nicht ausgewertet wird die erste, wenn, wenn falsch.

   if (nextWordLength > distanceFromWidth)

sollten wahrscheinlich ändern

   if (it == sentence.end())
         break;
   if (nextWordLength > distanceFromWidth)

Mit ziemlicher Sicherheit Ihres Fehler ist das Ergebnis:

*it = '\n';

Da in dem vorangehenden while-Schleife eines Ihrer Anhaltebedingung ist:

it != sentence.end()

Wenn es == sentence.end (), dann * it = '\ n' wird nicht fliegen

Es gibt mehr Fehler, aber das ist derjenige, der Ihr aktuelles Problem verursacht.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top