Boucle sans fin, ou autre... [Résolu]

Signaler
Messages postés
127
Date d'inscription
mardi 23 août 2005
Statut
Membre
Dernière intervention
9 mai 2011
-
Messages postés
127
Date d'inscription
mardi 23 août 2005
Statut
Membre
Dernière intervention
9 mai 2011
-
Bonjour tout le monde, voilà je fais une fonction semblable à trim() en
PHP. Seulement voilà, le programme reste planter au même endroit :



printf("Suppression des caracteres blancs de fin de chaine.\n");


i=taille-1;


while(i>0 &&


!isAlphaNum(chaine[i]) &&


!rechCar(caracteres,chaine[i],strlen(caracteres)) )


{


chaine[i]='\0';


i--;


}



Le programme affiche le contenue de printf() et c'est tout, il s'arrête là. Et je ne vois pas pouquoi.

svp aider moi... :'(

16 réponses

Messages postés
1787
Date d'inscription
lundi 22 novembre 2004
Statut
Membre
Dernière intervention
31 janvier 2009
2
#include <stdio.h>

#include <stdlib.h>

#include <string.h>





void SuppDevant(char *sz)

{

char Buff[128];

int Index = 0;

char *c = sz;



while(*c == ' ')

{

Index++;

c++;

}



strcpy(Buff, sz+Index);

strcpy(sz, Buff);

}



void SuppDerriere(char* sz)

{

char *d = sz + strlen(sz);

d--;



while(*d-- == ' ')

*d = 0;

}



void Trim(char *sz)

{

SuppDevant(sz);

SuppDerriere(sz);

}



int main(int argc, char *argv[])

{

char Buff[] = " Salut les enfants ";

Trim(Buff);

printf("%s", Buff);

system("PAUSE");

return 0;

}


if(!Meilleur("Joky")) return ERREUR;<
Messages postés
6535
Date d'inscription
lundi 16 décembre 2002
Statut
Modérateur
Dernière intervention
22 août 2010
7
Que valent taille, chaine, caractères...?
Messages postés
127
Date d'inscription
mardi 23 août 2005
Statut
Membre
Dernière intervention
9 mai 2011

taille c'est la paramètre passé à la fonction, je mets : sizeof(chaine)/sizeof(char), ce qui en théorie me retourne la taille du tableau de caractère y compris le '\0' de la fin.

chaine c'est la chaine de caractères que je passe à la fonction, c'est cette chaine dont je dois enlevé les ' ' et '\ '. caracteres c'est une chaine contenant les caractères pouvant intervenir dans chaine et qu'il faut préserver.
Messages postés
127
Date d'inscription
mardi 23 août 2005
Statut
Membre
Dernière intervention
9 mai 2011

Non en fait j'ai trouvé où ça plantais, c'est dans la fonction rechCar(...);, y a une boucle sans fin dedans.

Merci quand même de ton attention
Messages postés
127
Date d'inscription
mardi 23 août 2005
Statut
Membre
Dernière intervention
9 mai 2011

Donc voilà ma fonction trim(), il a des fonction à côté :

bool isMaj() // retourne vrai si le caractère est une majuscule

bool isMin() // retourne vrai si le caractère est une minuscule

bool isNum() // retourne vrai si le caractère est un chiffre

bool isAlphaNum() // regroupe l'ensemble des fonctions d'avant

bool rechCar() // recherche le caractère dans la chaine caracteres



void trim(char* chaine,int taille)


{


char *chaine2 = new char[taille];


memset(chaine2,0,sizeof(chaine2));


char caracteres[]="()[]',?.;:/"-_%éèê#*&@|";


int i=0,j;




while(i<taille &&


!isAlphaNum(chaine[i]) &&


!rechCar(caracteres,chaine[i],strlen(caracteres)) )


{

printf("chaine[%d]='%c' (%d)\n",i,chaine[i],chaine[i]);


chaine[i]='\0';


i++;


}



i=taille-1;


while(i>=0 &&


!isAlphaNum(chaine[i]) &&


!rechCar(caracteres,chaine[i],strlen(caracteres)) )


{

printf("%s\nchaine[%d]='%c' (%d)\n",chaine,i,chaine[i],chaine[i]);


chaine[i]='\0';


i--;


}



i=0;j=0;


while(i<taille && j<taille)


{


if( chaine[i]!='\0' )


chaine2[j] = chaine[i];


i++;j++;


}

memset(chaine,0,sizeof(chaine));

strcpy(chaine,chaine2);


delete[] chaine2;


}



pour faire simple, la fonction ne marche pas :-)
Messages postés
127
Date d'inscription
mardi 23 août 2005
Statut
Membre
Dernière intervention
9 mai 2011

OK, c'est le même principe que je voulais faire, ta boucle dans
suppDevant est infie j'ai l'impression. JE vais essayer de mettre ça en
oeuvre à ma sauce. merci

Mais pourquoi tu vérifis si le caractère est vide ?
Messages postés
1787
Date d'inscription
lundi 22 novembre 2004
Statut
Membre
Dernière intervention
31 janvier 2009
2
c'est pas le caractère vide, c'est un espace



Si le caractère est un espace, alors Index représente le nombre d'espace

ensuite on copie dans Buff, tout sz sauf les Index premiers espaces



Et pour les espaces derrière, on se place à la fin de la chaine, et on fé une marche arrière tant que c'est un espace,

et alors on coupe *d = 0



Voila ;)
if(!Meilleur("Joky")) return ERREUR;<
Messages postés
1787
Date d'inscription
lundi 22 novembre 2004
Statut
Membre
Dernière intervention
31 janvier 2009
2
Et non elle n'est pas infinie, parce que si le premier caractère n'est
pas un espace, il ne rentre pas dans la boucle, et donc Index = 0, donc
il y a bien 0 espace devant ;)
if(!Meilleur("Joky")) return ERREUR;<
Messages postés
6535
Date d'inscription
lundi 16 décembre 2002
Statut
Modérateur
Dernière intervention
22 août 2010
7
while(*d-- == ' ')
*d = 0;

Ca sert a rien de mettre des zeros partout, seul le dernier est important
while(*d-- == ' ');
*d = 0;

Les deux strcpy dans SuppDevant sont pas très efficaces. Il suffit en fait d'avoir le décalage (nombre d'espaces) et de faire
while(*(sz + dec))
{
*sz = *(sz + dec);
sz++;
}
*sz = 0;
Messages postés
6535
Date d'inscription
lundi 16 décembre 2002
Statut
Modérateur
Dernière intervention
22 août 2010
7
Au fait, bntrimR et bntrimL sont sans doute le must pour ca (ou carrément bntrim)
Voir ici par exemple: http://www.cppfrance.com/code.aspx?ID=10501
Messages postés
127
Date d'inscription
mardi 23 août 2005
Statut
Membre
Dernière intervention
9 mai 2011

Bon voilà la fonction trim() qui marche que je viens de terminer :



void trim(char* chaine,int taille)


{


char *chaine2 = new char[taille];

int i=0;




while(i<taille && (chaine[i]==' ' || chaine[i]=='\t') )


i++;

memset(chaine2,0,sizeof(chaine2));

strcpy(chaine2,chaine+i);

memset(chaine,0,sizeof(chaine));

strcpy(chaine,chaine2);

delete[] chaine2;



i=strlen(chaine)-1;


while(i>=0 && (chaine[i]==' ' || chaine[i]=='\t' || chaine[i]=='\r') )


{


chaine[i]='\0';


i--;


}

}



merci à vous tous
Messages postés
6535
Date d'inscription
lundi 16 décembre 2002
Statut
Modérateur
Dernière intervention
22 août 2010
7
memset(chaine2,0,sizeof(chaine2));

Ca ne va pas faire ce que tu veux, car sizeof chaine2 retournera TOUJOURS 4
Aussi, je trouve ca assez fort de faire une allocation pour une fonction trim!
Messages postés
21041
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
26
__declspec(naked) int __fastcall bntrim(char* psrc)
{ // ECX = psrc
__asm {
mov [esp-4], ecx
mov eax, ecx
Ltrm1:
mov dl, [ecx]
inc ecx
cmp dl, 32
je short Ltrm1
dec ecx
dec eax
Ltrm2:
mov dl, [ecx]
inc eax
inc ecx
mov [eax], dl
test dl, dl
jnz short Ltrm2
mov ecx, [esp-4]
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
}
}

La chaine est passée en registre à la fonction et tout est fait en interne en un minimum de cycles.
Vous aurez en plus le nombre de caractères restants dans la chaine en retour (utile pour chainage direct sans strcat).

ciao...
http://dev.winsysdev.com
BruNews, MVP VC++
Messages postés
127
Date d'inscription
mardi 23 août 2005
Statut
Membre
Dernière intervention
9 mai 2011

BruNews > ton idée est pas mal, enfin je ne connais pas à fond
l'assembleur. Pour le moment je ne cherche pas à optimiser mon code, il
est suffisament rapide comme ça.

Plus tard quand je me serais mis à l'assembleur je referais certaine de mes fonctions en assembleur histoire d'optimiser.



vecchio56 > à la place de sizeof(chaine2), je mets quoi ?
Messages postés
6535
Date d'inscription
lundi 16 décembre 2002
Statut
Modérateur
Dernière intervention
22 août 2010
7
strlen(chaine2); C'est comme ca qu'on trouve la taille d'un chaine
Messages postés
127
Date d'inscription
mardi 23 août 2005
Statut
Membre
Dernière intervention
9 mai 2011

strlen(chaine2) retourne le nombre de caractères de chaine2 avant le premier '\0', hors moi je veux mettre des '\0' sur la totalité des cases de chaine2, pour faire propre quoi.