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?
222
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 pourchar
. 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.la source
<algorithm>
pour que cela fonctionne.De gamedev
la source
::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
la source
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 :
la source
Vous pouvez utiliser cette solution pour supprimer un caractère:
la source
Salut, tu peux faire quelque chose comme ça. Cette fonction supprime tous les espaces.
J'ai fait une autre fonction, qui supprime tous les espaces inutiles.
la source
utilise le:
la source
Si vous voulez le faire avec une macro simple, en voici une:
Cela suppose que vous avez fait
#include <string>
bien sûr.Appelez-le ainsi:
la source
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-
utilisers.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 1mais comme mentionné par d'autres, l'effacement de l'idiome semble également correct.
la source
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.
la source
La source:
Référence tirée de ce forum.
la source
En C ++ 20, vous pouvez utiliser la fonction gratuite std :: erase
Exemple complet:
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
la source
Supprime tous les caractères d'espacement tels que les tabulations et les sauts de ligne (C ++ 11):
la source
sortie: 2CF4323CB9DE
la source
la source
length()
renvoie unsize_t
, pas unint
.erase()
prend unsize_type
, pas unint
. 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.
la source