Expressão: String iterator não dereferenciável
-
21-08-2019 - |
Pergunta
Estou tendo dificuldade em usar o std :: string :: iterators em c ++. Esse código compila Fine (ainda não obtendo saída correta, mas isso é culpa minha: TODO, FIX O algoritmo) no Dev-C ++, e eu não recebo erros de tempo de execução. O erro é com o Visual Studio Express 2008 C ++, onde estou recebendo um erro apontando para <xstring>: "Expression: string iterator não dereferenciável" e aponta para a linha 112 do arquivo <xstring>.
Minha depuração me diz que eu posso estar tentando desreferenciar após o fim da entrada da frase, mas não consigo ver onde. Alguém pode lançar alguma 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;
}
Solução
Em primeiro lugar, use o operador! = () Em iteradores, não operador <():
while (it != sentence.end())
Em segundo lugar, isso é para trás: while (*it != ' ' && it != sentence.end())
Você faz algo com o iterador, do que verifica se o iterador é válido. Em vez disso, você deve verificar se é válido primeiro:
while (it != sentence.end() && *it != ' ')
Em terceiro lugar, você deve usar o iterador ++ sobre o iterador ++, embora isso não esteja relacionado ao seu travamento.
Quarto, uma questão principal está aqui:
*it = '\n';
Por causa da verificação precedente, while (it != sentence.end()
, é possível alcançar essa desreferência do iterador enquanto estiver no final. Uma correção seria fazer isso:
if (it != sentence.end() && nextWordLength > distanceFromWidth)
Então agora, se você chegou ao fim, você para.
Depois de corrigir a edição anterior, agora o único problema é o seguinte:
//skip the space
++it;
Isso pressupõe que o personagem que você está pulando é de fato um espaço. Mas e o fim da string? Execute esta função com esta string:
"a test string " // <- space at end
E terá sucesso; Ele pula o espaço, colocando o iterador em end()
, o loop sai e o sucesso.
No entanto, sem o espaço, ele falhará, porque você chegou ao fim e está pulando pelo fim. Para consertar, adicione um cheque:
//skip the space
if (it != sentence.end())
{
++it;
}
Resultando neste 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;
}
Você pode notar que isso parece ter muitos cheques redundantes. Isso pode ser corrigido:
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;
}
Espero que isso ajude!
Outras dicas
while (*it != ' ' && it != sentence.end())
muda para
while (it != sentence.end() && *it != ' ')
Portanto, a segunda expressão não é avaliada se a primeira se falsa.
if (nextWordLength > distanceFromWidth)
provavelmente deveria mudar para
if (it == sentence.end())
break;
if (nextWordLength > distanceFromWidth)
Quase certamente seu erro é o resultado de:
*it = '\n';
Desde o anterior, enquanto o loop, uma de suas condições de parada é:
it != sentence.end()
Se == sentença.end (), então *it = ' n' não voará
Existem mais erros, mas é esse que está causando seu problema atual.