Je suis en train d’écrire un logiciel et il m’oblige à manipuler les données d’une page Web contenant libcurl. Lorsque je reçois les données, il y a des sauts de ligne supplémentaires pour une raison quelconque. Je dois trouver un moyen de ne permettre que les lettres, les chiffres et les espaces. Et supprimez tout le reste, y compris les sauts de ligne. Y at-il un moyen facile de faire cela? Merci.
Ecrivez une fonction qui prend une char
et retourne true
si vous souhaitez supprimer ce caractère ou false
si vous souhaitez la conserver:
bool my_predicate(char c);
Ensuite, utilisez l'algorithme std::remove_if
pour supprimer les caractères indésirables de la chaîne:
std::string s = "my data";
s.erase(std::remove_if(s.begin(), s.end(), my_predicate), s.end());
Selon vos besoins, vous pourrez peut-être utiliser l’un des prédicats de la bibliothèque standard, tel que std::isalnum
, au lieu d’écrire votre propre prédicat (vous avez dit que vous deviez faire correspondre les caractères alphanumériques et les espaces, alors peut-être que cela ne correspond pas exactement à vos besoins. ).
Si vous souhaitez utiliser la fonction std::isalnum
de la bibliothèque standard, vous aurez besoin d'un transtypage pour distinguer la fonction std::isalnum
dans l'en-tête C de la bibliothèque standard C <cctype>
(qui est celui que vous souhaitez utiliser) et le std::isalnum
dans l'en-tête C++ Standard Library <locale>
( qui ne correspond pas à celui que vous souhaitez utiliser, sauf si vous souhaitez effectuer un traitement de chaîne spécifique à l'environnement local):
s.erase(std::remove_if(s.begin(), s.end(), (int(*)(int))std::isalnum), s.end());
Cela fonctionne aussi bien avec l’un des conteneurs de séquence (y compris std::string
, std::vector
et std::deque
). Cet idiome est communément appelé l'idiome "effacer/supprimer". L'algorithme std::remove_if
fonctionnera également avec les tableaux ordinaires. Le std::remove_if
ne fait qu'un seul passage sur la séquence, de sorte qu'il a une complexité temporelle linéaire.
Les utilisations précédentes de std::isalnum
ne seront pas compilées avec std::ptr_fun
sans passer l'argument unary est requis, c'est pourquoi cette solution avec une fonction lambda devrait encapsuler la réponse correcte:
s.erase(std::remove_if(s.begin(), s.end(),
[]( auto const& c ) -> bool { return !std::isalnum(c); } ), s.end());
Si vous utilisez erase
, vous pouvez toujours parcourir et ne modifier que string
tous les caractères non alphanumériques.
#include <cctype>
size_t i = 0;
size_t len = str.length();
while(i < len){
if (!isalnum(str[i]) || str[i] == ' '){
str.erase(i,1);
len--;
}else
i++;
}
Quelqu'un de mieux avec le Standard Lib peut probablement le faire sans boucle.
Si vous utilisez uniquement un tampon char
, vous pouvez effectuer une boucle et si un caractère n'est pas alphanumérique, décaler tous les caractères après le caractère précédent (pour écraser le caractère incriminé):
#include <cctype>
size_t buflen = something;
for (size_t i = 0; i < buflen; ++i)
if (!isalnum(buf[i]) || buf[i] != ' ')
memcpy(buf[i], buf[i + 1], --buflen - i);
L'algorithme remove_copy_if standard serait très approprié pour votre cas.
#include <cctype>
#include <string>
#include <functional>
std::string s = "Hello World!";
s.erase(std::remove_if(s.begin(), s.end(),
std::not1(std::ptr_fun(std::isalnum)), s.end()), s.end());
std::cout << s << std::endl;
Résulte en:
"HelloWorld"
Vous utilisez isalnum
pour déterminer si chaque caractère est alphanumérique, puis ptr_fun
pour transmettre la fonction à not1
, ce qui N'A PAS la valeur renvoyée, vous laissant ainsi uniquement le contenu alphanumérique souhaité.
Vous pouvez utiliser l'algorithme remove-erase de cette façon -
// Removes all punctuation
s.erase( std::remove_if(s.begin(), s.end(), &ispunct), s.end());
Le code ci-dessous devrait fonctionner parfaitement pour la chaîne s
. Il utilise les bibliothèques <algorithm>
et <locale>
.
std::string s("He!!llo Wo,@rld! 12 453");
s.erase(std::remove_if(s.begin(), s.end(), [](char c) { return !std::isalnum(c); }), s.end());
Étendre juste un peu plus le code de James McNellis. Sa fonction est de supprimer des caractères d'alnum au lieu de ceux qui ne le sont pas.
Pour supprimer des caractères non-alnum d'une chaîne. (alnum = alphabétique ou numérique)
Déclarer une fonction (isalnum renvoie 0 si le caractère transmis n'est pas alnum)
bool isNotAlnum(char c) {
return isalnum(c) == 0;
}
Et puis écris ceci
s.erase(remove_if(s.begin(), s.end(), isNotAlnum), s.end());
alors votre chaîne est uniquement composée de caractères alnum.
Ce qui suit fonctionne pour moi.
str.erase(std::remove_if(str.begin(), str.end(), &ispunct), str.end());
str.erase(std::remove_if(str.begin(), str.end(), &isspace), str.end());
void remove_spaces(string data)
{ int i=0,j=0;
while(i<data.length())
{
if (isalpha(data[i]))
{
data[i]=data[i];
i++;
}
else
{
data.erase(i,1);}
}
cout<<data;
}