Pregunta

Estoy teniendo dificultades para usar std :: string :: iteradores en C ++. Este código compila bien (todavía no conseguir un resultado correcto, pero eso es mi culpa: TODO, fijar algoritmo) en Dev-C ++, y no consigo los errores de ejecución. El error es con Visual Studio Express 2008 C ++, donde estoy recibiendo un error señalando : "Expresión: iterador cadena no dereferencable". Y los puntos a la línea 112 del archivo

Mi depuración me dice que podría estar tratando de eliminar la referencia más allá del final de la entrada de frase, pero no puedo ver dónde. ¿Alguien puede arrojar algo de luz?

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;    
}
¿Fue útil?

Solución

En primer lugar, el uso del operador = () en iteradores, no debe utilizarse <():

while (it != sentence.end())

En segundo lugar, esto es hacia atrás: while (*it != ' ' && it != sentence.end())

Se hace algo con el repetidor, que compruebe si el iterador es válido. Más bien, debe comprobar si es válido en primer lugar:

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

En tercer lugar, se debe utilizar ++ iterador sobre iterador ++, aunque esto no está relacionado con su estrellarse.


En cuarto lugar, la cuestión principal es aquí:

*it = '\n';

Debido a la verificación precedente, while (it != sentence.end(), es posible llegar a eliminar la referencia que iterador mientras que ser al final. Una solución sería la de hacer esto:

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

Así que ahora si ha llegado al final, se detiene.


Después de fijar el número anterior, ahora el único problema es el siguiente:

//skip the space
++it;

Esto supone que el personaje va a omitir es de hecho un espacio. Pero qué pasa con el final de la cadena? Ejecutar esta función con esta cadena:

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

Y tendrá éxito; se salta el espacio, poniendo el iterador en end(), el bucle termina y el éxito.

Sin embargo, sin el espacio que se colgará, ya que han llegado al final, y está saltando más allá del final. Para corregir, añadir un cheque:

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

Como resultado de este código final:

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

Usted puede notar esto parece que tiene una gran cantidad de controles redundantes. Esto se puede solucionar:

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

Con suerte que ayuda!

Otros consejos

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

cambios a

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

lo que la segunda expresión no se evalúa si el primero si es falso.

   if (nextWordLength > distanceFromWidth)

probablemente debería cambiar a

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

Es casi seguro que el error es el resultado de:

*it = '\n';

Dado que en el anterior mientras bucle en uno de sus condiciones de parada es:

it != sentence.end()

Si == sentence.end (), entonces * es = '\ n' no va a volar

Hay más errores, pero eso es lo que está causando su problema actual.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top