SSCANF POUR SUPPRIMER DES ESPACES (COMME TRIM())

BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019 - 29 juil. 2007 à 17:54
cs_Lucky92 Messages postés 180 Date d'inscription mercredi 22 décembre 2004 Statut Membre Dernière intervention 16 août 2012 - 13 août 2007 à 13:24
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/43596-sscanf-pour-supprimer-des-espaces-comme-trim

cs_Lucky92 Messages postés 180 Date d'inscription mercredi 22 décembre 2004 Statut Membre Dernière intervention 16 août 2012 2
13 août 2007 à 13:24
Bonjour,

J'ai pris le parti de participer, avec un peu de retard, au concours du "code le plus lent du monde" !

Je précise que je navigue dans un monde parallèle :
- moins j'écris de code, mieux je me porte ;
- l'optimisation se fait au besoin et en dernier lieu ;
- l'arithmétique des pointeurs : ça pique mes yeux...

Voici ma version en c++ standard des fonctions trim(). Attention : à n'utiliser que dans des applications inefficaces !!!

////////////////////////////////////////////////////////////////////////////////
std::string& ltrim( std::string& str )
{
return str.erase( 0 , str.find_first_not_of( "[ \t]" ) );
}
////////////////////////////////////////////////////////////////////////////////
std::string& rtrim( std::string& str )
{
return str.erase( str.find_last_not_of( "[ \t]" ) + 1 , str.size() );
}
////////////////////////////////////////////////////////////////////////////////
std::string& trim( std::string& str )
{
return ltrim( rtrim( str ) );
}
////////////////////////////////////////////////////////////////////////////////
cs_vicenzo Messages postés 178 Date d'inscription mardi 16 août 2005 Statut Membre Dernière intervention 25 août 2010 1
31 juil. 2007 à 10:32
Ca c'est un post comme on les aime... ! Que d'action !

Sinon, pour DarkPoulpo, apparamment un trim est pour toi une action désuète et pas assez significtive pour être optimisée et dont on se fous du temps d'exécution.

Pour moi, au contraire il s'agit d'un opération critique qui doit être la plus optimisée possible car dans 90% des cas ou j'ai à l'utiliser, il s'agit de trimmer des champs de messages entre interfaces de commuunication au sein de systèmes d'information. Et la on doit traiter les infos en temps réel et gérer des centaines de messages par seconde.

Dans tous ls cas, il s'agit d'une routine de base et comme toute les routines de base, il faut de l'optimisation afin de laisser au developpeur le loisir de faire du code métier aussi lent q'il le souhaite.

Sinon, au sujet du C99, je suis d'accord avec Brunews, cela n'apoorte rien de vraiment bon (sauf les macros à arguments variables, c'est plutôt sympa)... En fait la révision 99 a été faite pour gommer un peu les différences entre C et c++ (sur l'ensemble C commun). Et puis Microsoft a clairement indiqué qu'il ne comptait pas du tout supporter cette norme et ne le fera jamais...
cs_Matt67 Messages postés 549 Date d'inscription samedi 6 septembre 2003 Statut Membre Dernière intervention 6 mars 2010 3
30 juil. 2007 à 22:38
Bonsoir,

Pour conclure, je dirais simplement que je n'ai plus VC++ donc peut pas tester ton exemple.
Par contre avec gcc (4.1.2), ça passe (les deux exemples, celui de BruNews et de SAK). Mais je répète, je ne dis pas que c'est bien. (même pas bien du tout avec l'exemple de BruNews).

Matt...
SAKingdom Messages postés 3212 Date d'inscription lundi 7 novembre 2005 Statut Membre Dernière intervention 16 février 2009 15
30 juil. 2007 à 21:42
T'as essayé de compiler mon exemple ? Moi ça me donne une erreur comme quoi toto n'est pas déclaré.

Pour conclure, je dirais simplement qu'en C, lorsqu'on a la possibilité d'optimiser quelque chose rapidement et facilement (commme un trim), on le fait. Sinon on se retrouve très vite avec un programme aussi lent que s'il avait été fais en .NET.
cs_Matt67 Messages postés 549 Date d'inscription samedi 6 septembre 2003 Statut Membre Dernière intervention 6 mars 2010 3
30 juil. 2007 à 21:26
Bonsoir,

Doucement, je n'ai pas dit que c'était bien ou que c'était une connerie, j'ai seulement dit que tu pouvais déclarer une variable quand tu en avais besoin, c'est tout.
Personnellement, je met toujours mes variables en début de bloc. Je suis d'accord avec toi BruNews, l'exemple que tu as donnée est parlant, c'est du n'importe quoi...

Matt...
darkpoulpo Messages postés 76 Date d'inscription lundi 21 mars 2005 Statut Membre Dernière intervention 29 novembre 2009
30 juil. 2007 à 21:13
pour le code, je suis partit du principe qu'on fournit le pointeur d'un char xxx[], et quon recupere celui ci. mais effectivement, j'ai omis cette partie, de toute facon, je ne l'avais pas ecrit pour savoir si le code marche, mais pour donner une idee de base.

Et ce n'est pas parcequ'on fait du C/C++ quon doit passer sa vie a tout optimiser. voila comme je le vois! chaque cas a sa reflection!

par contre on va clore le sujet, chacun pense ce qu'il veut, et ni vous ni moi, ne peut se permettre de dire que c'est lui qui a raison et que l'autre a tort, chaque cas a son contexte. quoi qu'il en soit, dans mon contexte, sscanf() ira largement, et il sera surrement pareil pour d'autres. Il n'existe pas UNE solution meme si brunews croit toujours la donner comme la parole de dieu. Chacun choisit le code qu'il veut pour faire tel ou tel truc, en fonction de son besoin, c'est tout.

Il me semble qu'il ya plus important dans la vie que de se prendre le choux sur des futilités comme le temps d'execution d'un trim()!
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
30 juil. 2007 à 19:25
Ne te parait pas une énorme connerie cette norme c99 ???

n = retourDeFunc();
int tab[n];
etc...

Quand on ne controle plus la mémoire, ce n'est plus du C.
SAKingdom Messages postés 3212 Date d'inscription lundi 7 novembre 2005 Statut Membre Dernière intervention 16 février 2009 15
30 juil. 2007 à 19:22
Essais de compiler ceci en C avec VC++:

printf("Bonjour ");
char toto[] = "a tous";
printf("%s\n", toto);
cs_Matt67 Messages postés 549 Date d'inscription samedi 6 septembre 2003 Statut Membre Dernière intervention 6 mars 2010 3
30 juil. 2007 à 19:10
Bonsoir,

SAKingdom a écrit :
Attention ici, ce n'est déjà plus du C. Les variables doivent être déclarées en début de fonction.

Ben, plus maintenant avec la norme c99, tu déclares ou tu veux (quand tu en as besoin).

Matt...
SAKingdom Messages postés 3212 Date d'inscription lundi 7 novembre 2005 Statut Membre Dernière intervention 16 février 2009 15
30 juil. 2007 à 16:28
"en ce qui concerne le caracteres "invalides" avant le texte, bein on s'en fou, vu qu'on incremente le pointeur sur le 1er caractere valide ou 0x00."

Test ton code sur cette chaine: " Bonjour je test un trim "
Tu verra ce que je veux dire. Ça donnera ceci:
" Bonjour je test un trim"

Pour le reste, tout à fais d'accord avec BruNews. Il existe d'autres langages beaucoup plus productif où le temps d'exécution n'est pas important (.NET, VB). Cependant, en C, on peut optimiser son code pour avoir un maximum de vitesse et ça, ce serait vraiment ridicule de complètement s'en passer.
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
30 juil. 2007 à 15:01
Façon de voir qui a amené à la disparition des offres d'emploi en natif.
Un "scriptologue" d'interprété ira encore plus vite que toi à faire son "prog" et donc coutera moins cher. Les patrons n'étant pas totalement stupides, à daube égale on prend la moins chère.
darkpoulpo Messages postés 76 Date d'inscription lundi 21 mars 2005 Statut Membre Dernière intervention 29 novembre 2009
30 juil. 2007 à 12:45
"C'est justement ce que je voulais éviter de faire. Inutile de mettre un 0 pour chaque caractère "invalide"."
bein quelque chose approchant ca plutot: (c'est juste l'idée)

while ( d >t && ((*(--d)) ' ' || (*d) == '\t')) ;
(*(++d)) = '\0';

en ce qui concerne le caracteres "invalides" avant le texte, bein on s'en fou, vu qu'on incremente le pointeur sur le 1er caractere valide ou 0x00.

Pour le reste c'est bien ce que je dis, tu me parles de jeux, ou d'OS, parle moi d'antivirus, de logiciel de mail, d'editer de texte, de logiciel de dessin, ... et tu verras qu'une seconde, on s'en fou du momeent que le tout tourne dans un laps de temps acceptable.

Ensuite, il vaut mieux un code reduit et facile a lire que 2km de code pour gagner 1sec la ou ce n'est pas juger important, surtout sur un trim(), rajouter 5, 10 lignes ou 15 ou 20..., bein moi ca me fait chier pour si peu, ca enleve de la visibilité sur la comprehension de ce qui est important dans le code, et faire une fonction en plus pour ca, c'est pareil, ca rajoute de la place en plus, pour un gain de temps qui n'est pas juger necessaire de gagner alors que sscanf() sera surement deja inclus dans ton code. Ya optimisation et optimisation, optimiser tout et nimporte quoi, c'est ne pas comprendre le moment ou c'est jugé necessaire et ou ca ne l'est pas et donc, oui, defois, selon le projet, il vaut mieux gagner en temps de devellopement qu'en temps d'execution. surtout que souvent, ca enleve de la clarté au code source (suffit de voir le code asm de brunews). voila, chacun son point de vue, tu as donné le tiens, j'ai donné le miens, mais serieux, se prenedre la tete pour le temps d'execution d'un trim(), ca devient ridicule!!

bonne continuation a toi aussi,
SAKingdom Messages postés 3212 Date d'inscription lundi 7 novembre 2005 Statut Membre Dernière intervention 16 février 2009 15
30 juil. 2007 à 04:52
while ((*t) == ' ' || (*t) == '\t') t++;
char *d=t;

Attention ici, ce n'est déjà plus du C. Les variables doivent être déclarées en début de fonction.

while ((*(--d)) ' ' || (*d) '\t') (*d) = '\0';

C'est justement ce que je voulais éviter de faire. Inutile de mettre un 0 pour chaque caractère "invalide".

De plus, ton code n'efface pas les caractères "invalides" avant le texte.

"essayer de gagner disons 1 seconde, c'est se prendre la tete pour pas grand chose, je pense qu'il y a plus important dans la vie, surtout quand on sait que tant tu va avoir ton swap qui travaille et va te ramer l'ordi au meme moment, ou que tu va te la glander a fumer une clope pour lequel, tu auras perdu 10sec rien que pour l'allumer!"

1 seconde pour un processeur c'est GIGANTESQUE. C'est une très mauvaise façon de penser. Heureusement que les concepteurs d'OS ne se sont pas dit la même chose car on aurait eu un DOS demandant une config pour faire tourner Vista.

À vrai dire, je suis sûr que si tous les programmeurs étaient des BruNews, des Michael Abrash, en gros, des programmeurs qui vise la vitesse d'exécution plutôt que la vitesse de production, on pourrait faire tourner Vista, Command & Conquer 3, Supreme commander, GTA 4 etc. sur une 500 mhz.
Mais ce n'est malheureusement pas le cas.

Sur ce, bonne continuation.
darkpoulpo Messages postés 76 Date d'inscription lundi 21 mars 2005 Statut Membre Dernière intervention 29 novembre 2009
30 juil. 2007 à 03:22
a vue de nez, se serait plus proche de ca:

unsigned int trim(char *t)
{
while ((*t) ' ' || (*t) '\t') t++;
char *d=t;
while ((*d) != '\0') d++;
while ((*(--d)) ' ' || (*d) '\t') (*d) = '\0';
return d-t+1;
}
darkpoulpo Messages postés 76 Date d'inscription lundi 21 mars 2005 Statut Membre Dernière intervention 29 novembre 2009
30 juil. 2007 à 03:10
comme tu dis, il fut un temps ou on devait passer par l'asm avant le c, seulement faut arreter de rester sur le passé, a part les jeux ou demoparty, la plupart des autres applications ont largement de quoi faire avec les processeurs actuels (sauf bidouille demandant de l'asm). l'assembleur, c'est bien jolie, mais tu sais deja qu'on va de plus en plus sur des langages de 4eme generation. si c'est pour revenir a chaque fois en arriere...

(au passage ton code asm ne prend pas la tabulation, va falloir rajouter 4 lignes)

de plus un trim(), c'est le genre de chose que l'on utilise rarement dans une boucle, alors essayer de gagner disons 1 seconde, c'est se prendre la tete pour pas grand chose, je pense qu'il y a plus important dans la vie, surtout quand on sait que tant tu va avoir ton swap qui travaille et va te ramer l'ordi au meme moment, ou que tu va te la glander a fumer une clope pour lequel, tu auras perdu 10sec rien que pour l'allumer!
SAKingdom Messages postés 3212 Date d'inscription lundi 7 novembre 2005 Statut Membre Dernière intervention 16 février 2009 15
30 juil. 2007 à 03:07
"paru bizzare" -> bizarre non ?

J'avais bricolé un truc similaire au code de BruNews en C mais ça donne vraiment un code chaotique.

char *trim (char *_str)
{
char *c;
// if(!_str || !*_str) return _str;
c = _str;
while(*_str == ' ') _str++;
if(*_str) {
while(1) {
*c = *_str;
if(!*++_str) break;
c++;
}
while(*c == ' ') c--;
c++;
}
*c = 0;
return c;
}

Je ne suis pas arrivé à faire mieux.
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
29 juil. 2007 à 23:29
On comprenait et pour cause, j'ai tapé "...qu'on peut entièrement codé..." alors que c'est codeR.

Doit pas être évident le bon apprentissage sans les bases. Je l'espère possible mais j'ai du mal à y croire.
cs_Matt67 Messages postés 549 Date d'inscription samedi 6 septembre 2003 Statut Membre Dernière intervention 6 mars 2010 3
29 juil. 2007 à 23:12
une paire de pointeurs aurait suffit, désolé.

Matt...
cs_Matt67 Messages postés 549 Date d'inscription samedi 6 septembre 2003 Statut Membre Dernière intervention 6 mars 2010 3
29 juil. 2007 à 21:26
Alors, une question, pourquoi fait on du c ? Codons tout en assembleur...
Disons, que ta fonction bntrim doit être optimisée, sans nul doute, mais reste incompréhensible pour celui qui n'a jamais fait d'assembleur. Par contre, je suis d'accord quand tu dis que pour un malheureux trim, on utilise les regex. Mais pour le concepteur, ça marche donc c'est OK, mais c'est pas optimisé. Comme tu l'as dit, une paire de pointeurs auraient suffit. Sans aller jusqu'à l'asm, le problème reste un bon apprentissage du c.

Matt...
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
29 juil. 2007 à 20:58
Le C n'est qu'un assembleur de haut niveau, c'est bien pour cela qu'on peut entièrement codé son prog en asm et le compiler avec un compilo C.
Il fut un temps où c'est ta réaction qui aurait paru bizzare, on n'aurait jamais formé un développeur au C sans lui avoir enseigné l'asm, c'est à dire qu'il puisse comprendre ce qui allait se passer avec son code.
Quand on voit un traitement de regex pour un simple trim, je me dis que la vieille école avait du bon.
cs_Matt67 Messages postés 549 Date d'inscription samedi 6 septembre 2003 Statut Membre Dernière intervention 6 mars 2010 3
29 juil. 2007 à 20:49
Bonsoir,

Me suis-je trompé de forum ?
Je suis sur le forum assembleur ?
Pourtant en haut à gauche de la page y a écrit : c/c++, bizarre.

Matt...
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
29 juil. 2007 à 17:54
C'est pour un concours de lenteur ?
Se code efficacement avec 2 pointeurs.
Sinon:
__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:
cmp eax, ecx
jna short Ltrm4
dec eax
cmp byte ptr[eax], 32
je short Ltrm3
inc eax
Ltrm4:
mov byte ptr[eax], 0
sub eax, ecx
ret 0
}
}
Rejoignez-nous