Domanda

Sto avendo un momento difficile utilizzando std :: string :: iteratori in C ++. Questo codice compila bene (ancora non ottenere corretta uscita, ma questo è colpa mia: TODO, fissare algoritmo) in Dev-C ++, e non ho ricevuto gli errori di runtime. L'errore è con Visual Studio Express 2008, C ++, dove sto ottenendo un errore che indica : "Espressione: stringa iteratore non dereferencable". E punti per la linea 112 del file

Il mio debug mi dice che potrebbe tentare di dereference oltre la fine dell'input frase, ma non riesco a vedere dove. Qualcuno può fare luce?

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;    
}
È stato utile?

Soluzione

In primo luogo, l'operatore uso = () su iteratori, senza operatore <():

while (it != sentence.end())

In secondo luogo, questo è indietro: while (*it != ' ' && it != sentence.end())

fare qualcosa con l'iteratore, di verificare se l'iteratore è valido. Piuttosto, si dovrebbe verificare se è valida prima:

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

In terzo luogo, è necessario utilizzare ++ iteratore su iteratore ++, anche se questo non è legato al vostro crash.


In quarto luogo, un problema principale è qui:

*it = '\n';

A causa del controllo precedente, while (it != sentence.end(), è possibile raggiungere quel dereferenziare iteratore pur essendo alla fine. Una correzione potrebbe essere quella di fare questo:

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

Così ora se si è raggiunta la fine, ci si ferma.


Dopo aver fissato il numero precedente, ora l'unico problema è questo:

//skip the space
++it;

Questo presuppone che il carattere si sta saltando è in realtà uno spazio. Ma per quanto riguarda la fine della stringa? Eseguire questa funzione con questa stringa:

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

E avrà successo; salta lo spazio, mettendo l'iteratore in end(), il ciclo si interrompe e il successo.

Tuttavia, senza lo spazio che andrà in crash, perché avete raggiunto la fine, e stanno per saltare oltre la fine. Per risolvere il problema, aggiungere un controllo:

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

Con conseguente questo codice finale:

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;    
}

Si potrebbe notare Questo sembra che ha un sacco di controlli ridondanti. Questo può essere risolto:

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;    
}

Si spera che aiuta!

Altri suggerimenti

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

modifiche

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

così la seconda espressione non viene valutata se il primo se falso.

   if (nextWordLength > distanceFromWidth)

dovrebbe probabilmente passare alla

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

Quasi certamente l'errore è il risultato di:

*it = '\n';

Dal momento che nel precedente ciclo while una delle tue condizioni di arresto è:

it != sentence.end()

Se == sentence.end (), allora * è = '\ n' non volerà

Non ci sono più errori, ma questo è quello che sta causando i problemi presenti.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top