Bonjour,
J'essaye d'utiliser les regex de regex.h en lazy mode i.e. :
si j'ai une chaine : "tititototatatoto" et que ma regex est "(.*?)toto",
je voudrais matcher juste titi et pas tititototata en back ref.
Avec ce petit programme perl ca marche, ca affiche titi:
perl -e '$_="tititototatatoto"; m/(.*?)toto/; print $1,"\n";'
avec ce programme C ca marche pas :
#include <regex.h>
int main(){
regex_t preg; regmatch_t pmatch[2];
regcomp (&preg, "(.*?)toto" , REG_EXTENDED|REG_ICASE);
regexec (&preg, "tititototatatoto", 2, pmatch,0);
size_t len = pmatch[1].rm_eo-pmatch[1].rm_so;
char * match = malloc(len+1);
memcpy(match,"tititototatatoto",len);
match[len] = 0;
printf("%s\n",match);
}
affiche tititototata...
Apparemment dans la doc que j'ai pu trouvé elle devrait prendre en compte le lazy mode...
Quelqu'un a une idée ?? (glibc2.0 Fedora 4)
Merci d'avance
# Une idee comme ça...
Posté par alf . Évalué à -1.
Non: int main (void) ou int main(int argc, char *argv[]) (ou une formulation équivalente pour la seconde). Tout autre prototype est une extension; et le int main() seul est un prototype incomplet.
regcomp() renvoie un code de sortie, il faut le vérifier. POSIX.2 [1] dit:
Note bien le undefined. En jargon C, ça veut vraiment dire indéfini, i.e. si tu accèdes au contenu de preg après une erreur de regcomp, tout peut se produire, du comportement que tu pensais obtenir, jusqu'au plantage, au crash disque, ou à des démons qui sortent de ton nez.
Idem pour regexec():
(enfin, tu n'es pas obligé pour regexec(), ça dépend du traitement que tu fais après. Pour un debug, je te conseille de vérifier le résultat).
Il faut vérifier le résultat de *alloc(). En cas d'échec de cete fonction, si tu ne fais pas cette vérification, tu déréférenceras un pointeur nul, d'où un comportement indéfini, soit la ligne suivante (memcpy() avec un len non nul), soit celle d'après (si len est nul).
De plus, il manque le #include <stdlib.h>, d'où encore un comportement indéfini: sans prototype de malloc visible, le compilateur est obligé de supposer que la fonction renvoie un int. Comme tu assignes cette valeur à un pointeur, cela viole une contrainte (6.5.16.1 du n1124), d'où un comportement indéfini. Si tu rajoutes un cast, le comportement n'est plus indéfini (les contraintes sont vérifiées), mais dépendant de l'implémentation (conversion d'entier en pointeur, 6.3.2.3p5, et 6 pour la conversion inverse). La bonne solution est donc de placer le #include qui va bien.
Un return 0; (ou return EXIT_SUCCES; avec l'include qui va bien) serait mieux, vu que main() renvoie un int. C99 autorise de ne pas le faire, mais c'est toujours mieux de finir une fonction ne renvoyant pas void par un return XX;.
[1] http://www.opengroup.org/onlinepubs/009695399/toc.htm Il faut s'inscrire, mais c'est gratuit et téléchargeable par la suite, ou consultable en ligne.
[^] # Re: Une idee comme ça...
Posté par Pierre Mallard . Évalué à 2.
[^] # Re: Une idee comme ça...
Posté par alf . Évalué à 0.
J'ai aussi remarqué (et c'est lié à ce qui précède) que tu ne testais pas les codes de retour des fonctions que tu appelles, ce qui t'empêche de savoir à partir d'où il s'écarte du comportement que tu attends. Si tu le faisais, tu pourrais cerner plus précisément le problème, et le résoudre assez vite (à mon avis). Etait-ce inutile de te le dire ? Avec le code que tu as posté, tu ne sais pas si regcomp plante, si c'est regexec, malloc, memcpy ou printf...
Pour le type de main(), désolé si ça t'énerve, mais il y a des gens dans d'autres fora ou newsgroups (pas moi, note) qui ne prennent même pas la peine de répondre à ceux qui ne savent pas comment l'écrire. J'ai pris la peine de te dire que ton code comportait un souci à ce niveau (plus précisément, et sauf erreur de ma part, utilisation d'une deprecated feature du C ISO, datant de l'époque K&R), et je t'ai donné les deux prototypes portables. J'aurais pu ne pas le faire. Libre à toi de ne pas prendre en compte mon message sur ce point.
Tiens, en passant, je n'avais pas fait attention que printf() et memcpy() n'avaient pas leur include non plus (respectivement stdio.h et stdlib.h). Pense à utiliser un niveau de warning suffisant pour ton compilateur (-O2 -Wall -Wextra pour gcc 4, par exemple (de tête)).
[^] # Re: Une idee comme ça...
Posté par PachaFonk . Évalué à 2.
Il aurait du poster tous le code de tous son projet, avec les includes et tout et tout.
Parce que bon, c'est pas parce que tu ne réponds pas à sa question que tu ne peux pas le sauver de la perdition.
[^] # Re: Une idee comme ça...
Posté par alf . Évalué à 1.
Et je ne prétends pas le sauver de la perdition, je note juste un certain nombre de problèmes (plus ou moins importants) dans son code.
Et non, je n'ai pas la réponse à sa question, je ne sais pas quel est l'endroit exact où son code s'écarte du comportement qu'il attend (à part peut-être ci-dessous). Mais j'ai repéré des endroits où le comportement est indéfini, i.e. tout et n'importe quoi peut se produire, y compris et surtout quelque chose qu'il ne veut pas (typiquement, un comportement indéfini peut causer une erreur de compilation, ou une erreur de segmentation à l'exécution si ça compile, ou un programme qui ne plante pas mais a un comportement incorrect), et je lui ai fait remarquer qu'en vérifiant les codes de retour des fonctions qu'il appelle, il pourrait cerner le problème plus facilement...
Après, je n'ai pas de compilateur C sous la main pour l'instant, je ne peux donc tester son code. Je n'ai pas utilisé regex.h, donc je ne peux voir s'il s'agit d'une erreur (évidente ou non) d'utilisation de ces fonctions.
A part peut-être, dans la doc POSIX (que j'ai donnée dans mon premier mail), je viens de trouver ça:
Donc le résultat qu'il obtient vient peut-être de là...
# PCRE
Posté par Pierre Mallard . Évalué à 2.
Pour cela, il faut utiliser la lib PCRE. (pcre_exec, pcre_compile ...)
Bon du coup je poste pas de code je risque de pas etre fully compatible ANSI C ISO 99... Des fois que ca jetterai le trouble chez quelques personnes... ANSI rigides...
[^] # Re: PCRE
Posté par PachaFonk . Évalué à 2.
Mais n'oublie pas la license au début... sinon tu ne sera pas "GNU compliant"
[^] # Re: PCRE
Posté par alf . Évalué à 1.
:)
Je n'ai rien contre les extensions au C (POSIX, GNU... ou tout ce qui tourne sur ta machine), par contre j'en ai contre les erreurs de programmation (en C, un comportement indéfini est une erreur). Quand un programme peut tenter d'accéder à une zone mémoire qui ne lui appartient pas, je ne vois pas en quoi c'est être rigide de dire qu'il y a un problème potentiel.
Peut-être savais-tu que c'était une erreur dans ton code d'exemple, dans ce cas tu pouvais l'écrire, même en commentaire dans le code.
De même pour les include, ça ne t'aurait pas coûté pas grand chose d'ajouter deux lignes à ton programme.
Pour d'autres points (main, ou return 0, par ex.), je voulais juste montrer une autre façon de faire (le main() sans argument est quand même deprecated depuis un moment...). Juste une question de style, sans plus.
Voilà. Maintenant, je suis content pour toi si tu as trouvé une solution à ton problème, qu'elle soit C ISO ou non d'aileurs, ou même dans un autre langage. L'important est que ta machine fasse çe que tu veux qu'elle fasse...
(et, cf. mon autre post, le problème ne viendrait peut-être pas directement de la glibc, mais des spécifications POSIX, que la glibc semble respecter pour le coup)
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.