Des chaines en C++ (Urgent!)

Résolu
GIRAFE ENRHUMEE Messages postés 44 Date d'inscription vendredi 21 janvier 2005 Statut Membre Dernière intervention 22 mai 2006 - 26 févr. 2005 à 20:43
Hylvenir Messages postés 364 Date d'inscription mercredi 11 février 2004 Statut Membre Dernière intervention 5 octobre 2006 - 28 févr. 2005 à 01:06
ce bout de code est censé servir à supprimer tous les espaces superflus à gauche et à droite d'une chaîne. Exemple :
" Bon jour " devient "Bon jour"

mais ça ne marche pas. Je reçois un message d'erreur au sujet de remove. no matching function for call to basic_string<etc...

int epurer_chaine(const string&s){
int a=0,i;
while(s[0]==' ')s.remove(0,1);
while(s[i=s.size()-1]==' '){
s.remove(i,1);
a=1;
}
return a;
}

16 réponses

vecchio56 Messages postés 6535 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 22 août 2010 14
27 févr. 2005 à 00:49
-erase n'est pas membre de la classe string;

-si tu passes ta chaine en const, tu auras du mal à la modifier sans faire raler le compilateur

-à quoi sert a?



Voila une solution qui ressemble a ce que tu avais écrit au début:



int epurer_chaine(string&s){

int a=0,i;

while(s[0]==' ')s.erase(s.begin());

while(s[i=s.size()-1]==' '){

s.erase(s.end() - 1);

a=1;

}

return a;

}
3
yoyo269 Messages postés 1403 Date d'inscription lundi 23 février 2004 Statut Membre Dernière intervention 11 janvier 2009 2
26 févr. 2005 à 21:14
Voilà ce que tu cherches :
/*Enlève les espaces du début*/
char * LTrim(char * Chaine)
{
unsigned int i = 0;
unsigned int j = 0;
unsigned int Longueur = strlen(Chaine);


if (Longueur > 0)
{
while (Chaine[i] == ' ') i++;
if (i > 0)
{
for (j = 0;j <= (Longueur - i);j++) Chaine[j] = Chaine[(i + j)];
Chaine[j] = 0;
}
}
return Chaine;
}/*Enlève les espaces de la fin*/
char * RTrim(char * Chaine)
{
unsigned int i = 0;
unsigned int Longueur = strlen(Chaine);


if (Longueur > 0)
{
i = Longueur;
while (Chaine[i - 1] == ' ') i--; if (i <Longueur) Chaine[i] 0;
}
return Chaine;
}/*Enlève les espaces du début et de la fin*/
char * Trim(char * Chaine)
{
LTrim(Chaine);
RTrim(Chaine);
return Chaine;
}

YOYO, @+.
YOYO
0
GIRAFE ENRHUMEE Messages postés 44 Date d'inscription vendredi 21 janvier 2005 Statut Membre Dernière intervention 22 mai 2006
26 févr. 2005 à 21:22
merci, mais j'essai de résoudre le probleme avec la classe string.
j'ai d'ailleurs recopier un exemple d'un livre, et on m'affiche le même message d'erreur.
0
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
26 févr. 2005 à 21:24
allez plaisanterie du soir... si on veut coder alors:

__declspec(naked) int __fastcall bntrim(char* psrc) // retour nombre char
{ // ECX = psrc
__asm {
mov [esp-4], ecx
mov eax, ecx
Ltrm1:
mov dl, [ecx]
inc ecx
cmp dl, 32
je short Ltrm1
dec ecx ; // 1er char != 32
dec eax
Ltrm2:
mov dl, [ecx]
inc eax
inc ecx
mov [eax], dl
test dl, dl
jnz short Ltrm2
mov ecx, [esp-4] ; // eax est zero final
Ltrm3:
mov byte ptr[eax], 0
cmp eax, ecx
jna short Ltrm4
dec eax
cmp byte ptr[eax], 32
je short Ltrm3
inc eax
Ltrm4:
sub eax, ecx
ret 0
}
}

servirait à quoi de retourner le pointeur char* qu'on reçoit, l'appelant l'a déjà puisqu'il le passe à la func.

ciao...
BruNews, MVP VC++
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
GIRAFE ENRHUMEE Messages postés 44 Date d'inscription vendredi 21 janvier 2005 Statut Membre Dernière intervention 22 mai 2006
26 févr. 2005 à 21:29
Ton message ne m'est d'aucune aide. Si tu peux m'aider, merci de me répondre.
0
Hylvenir Messages postés 364 Date d'inscription mercredi 11 février 2004 Statut Membre Dernière intervention 5 octobre 2006 2
27 févr. 2005 à 00:46
:)

j'adore la réponse de brunews...



Pour ta réponse, cherche un peu en utilisant

find_first_not_of de la classe std::string par exemple.




Ma participation à la saturation du net:
http://hylvenir.free.fr
0
Hylvenir Messages postés 364 Date d'inscription mercredi 11 février 2004 Statut Membre Dernière intervention 5 octobre 2006 2
27 févr. 2005 à 01:32
Si on veut pas coder ( ou si on travaille sur un PA-RISC :) )



string ltrim( const string& s, const char* c = " " )

{

string::size_type found = s.find_first_not_of( c );

if ( found == string::npos )

found = s.size();

return string( s, found );

}



// j'ai viré le a pour l'occasion.

Vechio56, quand tu écris erase, faut lire remove ;)




Ma participation à la saturation du net:
http://hylvenir.free.fr
0
Hylvenir Messages postés 364 Date d'inscription mercredi 11 février 2004 Statut Membre Dernière intervention 5 octobre 2006 2
27 févr. 2005 à 01:40
si la chaine est " ";


s.size() vaut 0 à la fin de la première boucle, donc

accès à s[-1]....





int epurer_chaine(string&s){

int a=0,i;

while(s[0]==' ')s.erase(s.begin());

while(s[i=s.size()-1]=='
'){
/// <-------- bug

s.erase(s.end() - 1);

a=1;

}

return a;

}

Ma participation à la saturation du net:
http://hylvenir.free.fr
0
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
27 févr. 2005 à 11:06
Voila qu'il a enfin sa réponse et, cerise sur le gateau, y a même toutes chances que ce soit plus lent qu'un 'Trim' VB.
Il en faut pour tous les gouts...

ciao...
BruNews, MVP VC++
0
Hylvenir Messages postés 364 Date d'inscription mercredi 11 février 2004 Statut Membre Dernière intervention 5 octobre 2006 2
27 févr. 2005 à 13:29
Entre une réponse asm

et une réponses bugguée, mon coeur balance...



Il est vraiment aussi mauvais que ça cl ?


Ma participation à la saturation du net:
http://hylvenir.free.fr
0
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
27 févr. 2005 à 13:46
while(s[0]==' ')s.erase(s.begin());
tu imagines combien de fois ça parcourt la chaine au complet et autant d'alloc desalloc, un vrai poème...
Dans tous les cas, Hylvenir, je ne vois pas tellement d'autre soluce avec des 'string'.

Je te rassure sur ma func ASM, aucun bug depuis des années qu'elle tourne. Niveau perf, sera dur à battre.

ciao...
BruNews, MVP VC++
0
Hylvenir Messages postés 364 Date d'inscription mercredi 11 février 2004 Statut Membre Dernière intervention 5 octobre 2006 2
27 févr. 2005 à 14:44
argh... c'est bien ce qu'il me semblait.

C'est pas ma solution ça, c'est la solution de vecchio. (j'indiquais juste la ligne

de son bug). je te confirme que c'est assez moyen comme méthode.

(je suis étonné que ce soit la solution acceptée d'ailleurs).



En fait voici (IHMO) deux autres solutions selon le besoin.

La première trimp_cpp va allouer une nouvelle chaîne (ce que ne fait pas ta fonction

asm et qui prend pas mal de temps) donc plus lente ( +-20 % qu'une

fonction C avec un strdup ). Mais pratique car on a directement une nouvelle chaine.

La deuxième se contente de dire où sont les bornes valides de la chaine.

Il n'y a pas d'allocation mais juste qun parcours de chaine. Elle ressemble plus

à la function asm mais en fait un peu moins (ne touche pas la chaîne d'origine).

La première pourrait être codée avec la deuxième (un truc de l'exemple 3)



// exemple 1 : equivaudrait à un C avec strdup / free sans la sécurité du C++

string trim_cpp( const string& str, const char* trim = " " )

{

string::size_type debut = str.find_first_not_of( trim );

if ( debut == string::npos ) return "";

return string( str, debut, str.find_last_not_of( trim ) - debut + 1 );

}



// exemple 2 : se contente de déplacer 2 pointeurs aux bons endroits

pair< string::size_type,string::size_type>

trim_cpp_light( const string& str, const char* trim = " " )

{

return std::make_pair( str.find_first_not_of( trim ), str.find_last_not_of( trim ) );

}



// non testée mais c'est l'idée. Utiliser le 2 pour faire le 1 - facilite les tests.

string trim_cpp( const string& str, const char* trim = " " )

{

pair< string::size_type,string::size_type> tmp = trim_cpp_light( str, trim );

if ( tmp.first == tmp.second ) return "";

return string( s, tmp.first, tmp.second-tmp.first + 1 );

}


Pour ta func asm je ne doute pas que tu l'ai testé mais je ne peux pas m'empêcher

de penser au temps qu'il t'a fallu pour l'écrire, la tester et le temps qu'il faudrait pour quequ'un

d'autre de la comprendre, la vérifier, la faire évoluer etc... (puis elle voudra pas

compiler sous hppa ;), alors qu'un équivalent C le ferait).

Globalement, je ne suis pas assez riche pour programmer en assembleur.

Sans compter que je ne suis même pas sûr qu'un compilo ne donne pas une

version plus rapide du même algo à partir du C (à voir l'asm n'est pas ma

spécialité mais j'ai déjà vu des cas, '-s' est mon ami). Faudrait me dire ce qu'elle

fait exactement pour faire le test sur ce cas.



//Ma participation à la saturation du net:
//http://hylvenir.free.fr
0
vecchio56 Messages postés 6535 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 22 août 2010 14
27 févr. 2005 à 15:27
Je sais que ma solution est mauvaise puisqu'a chaque fois il décale
toute la chaine à gauche. Je donnais ca pour dire de remplacer remove
(qui n'existe pas) par erase.
0
Hylvenir Messages postés 364 Date d'inscription mercredi 11 février 2004 Statut Membre Dernière intervention 5 octobre 2006 2
27 févr. 2005 à 19:03
Pour le fun... une version C (presque aussi rapide -10% que la version asm mais portable)

doit pouvoir s'optimiser (j'ai pas beaucoup réfléchit surtout testé)



int trim( char* str )

{

char* begin = str;

char* curBegin = str;

for( ;*str && *str == ' '; ++str ); // 1er != ' '



char* curEnd curBegin, *end str;

for( ; *curBegin *end *str; ++curBegin, ++end, ++str )

if ( *str !' ' ) curEnd curBegin; // dernier != ' '



if ( *curEnd ) *++curEnd = '\0';



return curEnd - begin; // taille de la chaine

}
0
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
27 févr. 2005 à 19:19
for( ;*str && *str == ' '; ++str ); // 1er != ' '
pourrait faire en + simplement écrit:
while(*str == 32) str++;

ciao...
BruNews, MVP VC++
0
Hylvenir Messages postés 364 Date d'inscription mercredi 11 février 2004 Statut Membre Dernière intervention 5 octobre 2006 2
28 févr. 2005 à 01:06
oui c'est clair.

j'ai vu ça dans la soirée.



C'est surtout le if final dont j'aimerais bien me

passer mais j'ai pas eu le temps de trouver.

// Ma participation à la saturation du net:
// http://hylvenir.free.fr
0
Rejoignez-nous