Quelle est la meilleure façon de supprimer des espaces d'une chaîne en C ++? Je pourrais parcourir tous les caractères et créer une nouvelle chaîne, mais y a-t-il une meilleure façon?
Quelle est la meilleure façon de supprimer des espaces d'une chaîne en C ++? Je pourrais parcourir tous les caractères et créer une nouvelle chaîne, mais y a-t-il une meilleure façon?
Réponses:
La meilleure chose à faire est d'utiliser l'algorithme remove_if
et isspace:
remove_if(str.begin(), str.end(), isspace);
Maintenant, l'algorithme lui-même ne peut pas changer le conteneur (seulement modifier les valeurs), donc il mélange réellement les valeurs autour et renvoie un pointeur vers l'endroit où la fin devrait être maintenant. Nous devons donc appeler string :: erase pour modifier réellement la longueur du conteneur:
str.erase(remove_if(str.begin(), str.end(), isspace), str.end());
Nous devons également noter que remove_if fera au plus une copie des données. Voici un exemple d'implémentation:
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
après. Cela retournera le résultat correct.
isspace
est UB pour tous les jeux de caractères sauf ASCII 7 bits d'origine. C99 §7.4 / 1. cela ne me surprend pas qu'il ait été surévalué à hauteur de 71 voix à l'heure actuelle, bien qu'il s'agisse de très mauvais conseils.
isspace
, pour tous les caractères non ASCII, avec le choix de signature par défaut en pratique pour char
. Il a donc un comportement indéfini . Je le répète parce que je soupçonne une tentative délibérée de noyer ce fait dans le bruit.
std::string::iterator end_pos = std::remove(str.begin(), str.end(), ' ');
str.erase(end_pos, str.end());
<algorithm>
pour que cela fonctionne.
De gamedev
string.erase(std::remove_if(string.begin(), string.end(), std::isspace), string.end());
::isspace
est UB.
Pouvez-vous utiliser 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);
celui mentionné par Matt Price. Je ne sais pas pourquoi. En fait, tous les éléments boost, qui ont des alternatives STL, sont plus lents que ceux gcc correspondants (tous ceux que j'ai testés). Certains d'entre eux sont extrêmement lents! (jusqu'à 5 fois dans les insertions unordered_map) C'est peut-être à cause du cache CPU de l'environnement partagé ou quelque chose comme ça.
Pour le découpage, utilisez des algorithmes de chaîne boost :
#include <boost/algorithm/string.hpp>
using namespace std;
using namespace boost;
// ...
string str1(" hello world! ");
trim(str1); // str1 == "hello world!"
Vous pouvez utiliser cette solution pour supprimer un caractère:
#include <algorithm>
#include <string>
using namespace std;
str.erase(remove(str.begin(), str.end(), char_to_remove), str.end());
Salut, tu peux faire quelque chose comme ça. Cette fonction supprime tous les espaces.
string delSpaces(string &str)
{
str.erase(std::remove(str.begin(), str.end(), ' '), str.end());
return str;
}
J'ai fait une autre fonction, qui supprime tous les espaces inutiles.
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);
}
utilise le:
string replace = replaceinString(thisstring, " ", "%20");
string replace2 = replaceinString(thisstring, " ", "-");
string replace3 = replaceinString(thisstring, " ", "+");
Si vous voulez le faire avec une macro simple, en voici une:
#define REMOVE_SPACES(x) x.erase(std::remove(x.begin(), x.end(), ' '), x.end())
Cela suppose que vous avez fait #include <string>
bien sûr.
Appelez-le ainsi:
std::string sName = " Example Name ";
REMOVE_SPACES(sName);
printf("%s",sName.c_str()); // requires #include <stdio.h>
J'ai utilisé le travail ci-dessous pendant longtemps - je ne suis pas sûr de sa complexité.
s.erase(std::unique(s.begin(),s.end(),[](char s,char f){return (f==' '||s==' ');}),s.end());
lorsque vous voulez supprimer du caractère ' '
et certains par exemple -
utiliser
s.erase(std::unique(s.begin(),s.end(),[](char s,char f){return ((f==' '||s==' ')||(f=='-'||s=='-'));}),s.end());
De même, augmentez simplement le ||
nombre de caractères que vous souhaitez supprimer n'est pas 1
mais comme mentionné par d'autres, l'effacement de l'idiome semble également correct.
string removeSpaces(string word) {
string newWord;
for (int i = 0; i < word.length(); i++) {
if (word[i] != ' ') {
newWord += word[i];
}
}
return newWord;
}
Ce code prend essentiellement une chaîne et parcourt chaque caractère qu'il contient. Il vérifie ensuite si cette chaîne est un espace blanc, si ce n'est pas le cas, le caractère est ajouté à une nouvelle chaîne.
#include <algorithm> using namespace std; int main() { . . s.erase( remove( s.begin(), s.end(), ' ' ), s.end() ); . . }
Référence tirée de ce forum.
En C ++ 20, vous pouvez utiliser la fonction gratuite std :: erase
std::string str = " Hello World !";
std::erase(str, ' ');
Exemple complet:
#include<string>
#include<iostream>
int main() {
std::string str = " Hello World !";
std::erase(str, ' ');
std::cout << "|" << str <<"|";
}
J'imprime | de sorte qu'il est évident que l'espace au début est également supprimé.
remarque: cela supprime uniquement l'espace, pas tous les autres caractères possibles qui peuvent être considérés comme des espaces, voir https://en.cppreference.com/w/cpp/string/byte/isspace
Supprime tous les caractères d'espacement tels que les tabulations et les sauts de ligne (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;
sortie: 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()
renvoie un size_t
, pas un int
. erase()
prend un size_type
, pas un int
. La fonction échouera probablement si deux espaces consécutifs sont rencontrés car l'index est toujours incrémenté. Si un espace est supprimé, la boucle lira au-delà des limites de la chaîne. Vous devriez probablement supprimer cette réponse car elle a besoin de beaucoup d'aide.
J'ai bien peur que ce soit la meilleure solution à laquelle je puisse penser. Mais vous pouvez utiliser reserve () pour pré-allouer la mémoire minimale requise à l'avance pour accélérer un peu les choses. Vous vous retrouverez avec une nouvelle chaîne qui sera probablement plus courte mais qui occupe la même quantité de mémoire, mais vous éviterez les réallocations.
EDIT: Selon votre situation, cela peut entraîner moins de frais généraux que les personnages enchevêtrés.
Vous devriez essayer différentes approches et voir ce qui vous convient le mieux: il se peut que vous n'ayez aucun problème de performances.