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?
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?
Respostas:
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 para char
. Assim, tem um comportamento indefinido . Estou repetindo porque suspeito de uma tentativa deliberada de afogar esse fato no barulho.
std::string::iterator end_pos = std::remove(str.begin(), str.end(), ' ');
str.erase(end_pos, str.end());
<algorithm>
para que isso funcione.
De gamedev
string.erase(std::remove_if(string.begin(), string.end(), std::isspace), string.end());
::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
erase_all(str, " ");
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 :
#include <boost/algorithm/string.hpp>
using namespace std;
using namespace boost;
// ...
string str1(" hello world! ");
trim(str1); // str1 == "hello world!"
Você pode usar esta solução para remover um caractere:
#include <algorithm>
#include <string>
using namespace std;
str.erase(remove(str.begin(), str.end(), char_to_remove), str.end());
Oi, você pode fazer algo assim. Esta função exclui todos os espaços.
string delSpaces(string &str)
{
str.erase(std::remove(str.begin(), str.end(), ' '), str.end());
return str;
}
Eu criei outra função, que exclui todos os espaços desnecessários.
string delUnnecessary(string &str)
{
int size = str.length();
for(int j = 0; j<=size; j++)
{
for(int i = 0; i <=j; i++)
{
if(str[i] == ' ' && str[i+1] == ' ')
{
str.erase(str.begin() + i);
}
else if(str[0]== ' ')
{
str.erase(str.begin());
}
else if(str[i] == '\0' && str[i-1]== ' ')
{
str.erase(str.end() - 1);
}
}
}
return str;
}
string replaceinString(std::string str, std::string tofind, std::string toreplace)
{
size_t position = 0;
for ( position = str.find(tofind); position != std::string::npos; position = str.find(tofind,position) )
{
str.replace(position ,1, toreplace);
}
return(str);
}
use-o:
string replace = replaceinString(thisstring, " ", "%20");
string replace2 = replaceinString(thisstring, " ", "-");
string replace3 = replaceinString(thisstring, " ", "+");
Se você quiser fazer isso com uma macro fácil, aqui está uma:
#define REMOVE_SPACES(x) x.erase(std::remove(x.begin(), x.end(), ' '), x.end())
Isso pressupõe que você tenha feito, é #include <string>
claro.
Chame assim:
std::string sName = " Example Name ";
REMOVE_SPACES(sName);
printf("%s",sName.c_str()); // requires #include <stdio.h>
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, -
use
s.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 1
mas, como mencionado por outros, o idioma apagar e remover também parece bom.
string removeSpaces(string word) {
string newWord;
for (int i = 0; i < word.length(); i++) {
if (word[i] != ' ') {
newWord += word[i];
}
}
return newWord;
}
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.
#include <algorithm> using namespace std; int main() { . . s.erase( remove( s.begin(), s.end(), ' ' ), s.end() ); . . }
Referência retirada deste fórum.
No C ++ 20, você pode usar a função livre std :: erase
std::string str = " Hello World !";
std::erase(str, ' ');
Exemplo completo:
#include<string>
#include<iostream>
int main() {
std::string str = " Hello World !";
std::erase(str, ' ');
std::cout << "|" << str <<"|";
}
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
Remove todos os caracteres de espaço em branco , como guias e quebras de linha (C ++ 11):
string str = " \n AB cd \t efg\v\n";
str = regex_replace(str,regex("\\s"),"");
string str = "2C F4 32 3C B9 DE";
str.erase(remove(str.begin(),str.end(),' '),str.end());
cout << str << endl;
saída: 2CF4323CB9DE
string removespace(string str)
{
int m = str.length();
int i=0;
while(i<m)
{
while(str[i] == 32)
str.erase(i,1);
i++;
}
}
length()
retorna a size_t
, não uma int
. erase()
leva um size_type
, não um int
. 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.