Qual é a maneira preferida de remover espaços de uma seqüência de caracteres em C ++? Eu poderia percorrer todos os personagens e criar uma nova string, mas existe uma maneira melhor?
222
A melhor coisa a fazer é usar o algoritmo remove_if
e o isspace:
remove_if(str.begin(), str.end(), isspace);
Agora, o próprio algoritmo não pode alterar o contêiner (apenas modificar os valores); portanto, embaralha os valores e retorna um ponteiro para onde o final agora deve estar. Portanto, precisamos chamar string :: erase para modificar o comprimento do contêiner:
str.erase(remove_if(str.begin(), str.end(), isspace), str.end());
Também devemos observar que remove_if fará no máximo uma cópia dos dados. Aqui está uma implementação de exemplo:
template<typename T, typename P>
T remove_if(T beg, T end, P pred)
{
T dest = beg;
for (T itr = beg;itr != end; ++itr)
if (!pred(*itr))
*(dest++) = *itr;
return dest;
}
erase
depois. Isso retornará o resultado correto.isspace
é UB para todos os conjuntos de caracteres, exceto o ASCII original de 7 bits. C99 §7.4 / 1. isso não surpreende -me que ele tenha sido upvoted da ordem de 71 votos por agora, apesar de ser muito maus conselhos.isspace
, para todos os caracteres não ASCII, com a opção padrão prática de assinatura parachar
. Assim, tem um comportamento indefinido . Estou repetindo porque suspeito de uma tentativa deliberada de afogar esse fato no barulho.fonte
<algorithm>
para que isso funcione.De gamedev
fonte
::isspace
é UB.Você pode usar o Boost String Algo? http://www.boost.org/doc/libs/1_35_0/doc/html/string_algo/usage.html#id1290573
fonte
remove_if(str.begin(), str.end(), isspace);
mencionado por Matt Price. Não sei porque. Na verdade, todas as coisas de impulso, que têm alternativas STL, são mais lentas que as correspondentes do gcc (todas as que testei). Alguns deles são imensamente mais lentos! (até 5 vezes em inserções unordered_map) Talvez seja por causa do cache da CPU do ambiente compartilhado ou algo parecido.Para aparar, use algoritmos de seqüência de impulso :
fonte
Você pode usar esta solução para remover um caractere:
fonte
Oi, você pode fazer algo assim. Esta função exclui todos os espaços.
Eu criei outra função, que exclui todos os espaços desnecessários.
fonte
use-o:
fonte
Se você quiser fazer isso com uma macro fácil, aqui está uma:
Isso pressupõe que você tenha feito, é
#include <string>
claro.Chame assim:
fonte
Usei o trabalho abaixo por muito tempo - não tenho certeza sobre sua complexidade.
s.erase(std::unique(s.begin(),s.end(),[](char s,char f){return (f==' '||s==' ');}),s.end());
quando você deseja remover caracteres
' '
e alguns, por exemplo,-
uses.erase(std::unique(s.begin(),s.end(),[](char s,char f){return ((f==' '||s==' ')||(f=='-'||s=='-'));}),s.end());
Da mesma forma, apenas aumente
||
se o número de caracteres que você deseja remover não for 1mas, como mencionado por outros, o idioma apagar e remover também parece bom.
fonte
Esse código basicamente pega uma string e interage com todos os caracteres nela. Em seguida, verifica se essa sequência é um espaço em branco; caso contrário, o caractere é adicionado a uma nova sequência.
fonte
Fonte:
Referência retirada deste fórum.
fonte
No C ++ 20, você pode usar a função livre std :: erase
Exemplo completo:
Eu imprimo | de modo que é óbvio que o espaço no início também é removido.
nota: isso remove apenas o espaço, e não todos os outros caracteres possíveis que podem ser considerados espaços em branco, consulte https://en.cppreference.com/w/cpp/string/byte/isspace
fonte
Remove todos os caracteres de espaço em branco , como guias e quebras de linha (C ++ 11):
fonte
saída: 2CF4323CB9DE
fonte
fonte
length()
retorna asize_t
, não umaint
.erase()
leva umsize_type
, não umint
. A função provavelmente falhará se dois espaços consecutivos forem encontrados, pois o índice é sempre incrementado. Se um espaço for removido, o loop lerá além dos limites da string. Você provavelmente deve excluir esta resposta, pois precisa de muita ajuda.Receio que seja a melhor solução em que consigo pensar. Mas você pode usar reserve () para pré-alocar previamente a memória mínima necessária para acelerar um pouco as coisas. Você terminará com uma nova sequência que provavelmente será mais curta, mas ocupará a mesma quantidade de memória, mas evitará realocações.
EDIT: Dependendo da sua situação, isso pode resultar em menos sobrecarga do que personagens confusos.
Você deve tentar abordagens diferentes e ver o que é melhor para você: talvez você não tenha nenhum problema de desempenho.
fonte