1

Si une brute en C passe par là....

voila le problème:

Je travaille sur un programme qui devra tourner sur des vieilles machines (style des vieux sgi/ibm/sun).
J'ai découvert la fonction asprintf à la suite de recherche pare rapport à ce dont j'ai besoin,
Pour info, cette fonction fait comme sprintf, sauf qu'en plus, elle gere l'allocation memoire pour le buffer où sera stocker le resultat.Bref, c'est du bonheur.
seulement, elle n'est pas standart.Je dois donc mettre son source dans mon code.Seulement, mes compétence sont prise en defaut.
/* alias de la fonction GNU etendue asprintf (non standart) Cette fonction formatte une sortie dans un buffer, qui est alloué dynamiquement. Penser à 'free' le buffer quand on a finis de l'utiliser. */ int nabprintf(char *str,const char *format, ...) {      int str_size=1024;      int mem_size;      va_list ap,aq;      char *buffer;      /*initialisation argument 'variadique'*/            va_copy (aq ,ap);      va_end(ap);      if((buffer=(char *)malloc(str_size*sizeof(char)))==NULL)      {           fprintf(stderr,"L'alocation de memoire a echouer (%d octets demandé)\n",str_size);      }      mem_size=str_size;      while(str_size <0 || str_size>=mem_size)      {           va_copy (aq ,ap);           va_end(ap);           va_start (aq ,format);           str_size=snprintf(buffer,mem_size,format,aq); /*le problème est ici*/           printf("verification:\n");           printf("format:%s\n",format);           printf("buffer:%s\n",buffer);           va_end(aq);                      if(str_size <0)           {                fprintf(stderr,"Une erreur s'est produite durant l'execution de snprintf\n");                return FALSE;           }           if(str_size>=mem_size)           {                char *ptr;                fprintf(stderr,"le resultat de snprintf est trop grand, realocation de memoire %d->%d\n",mem_size,str_size);                if((ptr=(char *)realloc(buffer,str_size*sizeof(char)))==NULL)                {                     fprintf(stderr,"L'alocation de memoire a echouer (%d octets demandé),neanmoins, le pointeur reste neanmoins intact\n",str_size);                     return FALSE;                }                else                {                     buffer=ptr;                }           }      }      return TRUE; } /*!  \param conn La connexion monté sur la BDD  \param clef_adapt Buffer de char contenant la clef de l'adaptateur local à effacer.ne doit pas être NULL.  \return TRUE si pas d'erreur, FALSE sinon. */ int SuppAdaptLocal(PGconn *conn,char *clef_adapt) {      char *requete;/*on utilise une variable car la requete n'est pas statique*/      int str_size=-1;      int mem_size=1024;      PGresult *res;      if(clef_adapt==NULL)      {                fprintf(stderr,"erreur:le pointeur clef_adapt est NULL.\n");                return FALSE;      }      nabprintf(requete,"DELETE FROM adaptateurs_locaux WHERE clef=%s",clef_adapt);      res = PQexec(conn,requete);      free(requete);      return TRUE; }

Ce que je veux faire:

recuperer un nombre d'argument variable, et le forwarder tel quel sur une fonction de type printf.
------------------------------------
| numero |   nom_adapt  |   clef   |
------------------------------------
|      0 |     chouette |  1321652 |
------------------------------------
|      1 |  steak hache |   986325 |
------------------------------------
|      2 | machin chose |     6325 |
------------------------------------
|      3 |       bidule |   164325 |
------------------------------------

Choisissez un adaptateur local (de 0 a 3) : 2
verification:
format: DELETE FROM adaptateurs_locaux WHERE clef=%s
buffer: DELETE FROM adaptateurs_locaux WHERE clef=Ððÿ¿Ððÿ¿&#9618;õÿ¿¯š
clef adaptateur distant effacée:6325


je voudrais arriver à un truc du style

buffer: DELETE FROM adaptateurs_locaux WHERE clef=6325



je pense que je suis pas tres loin de la verité, il ne manque pas grand chose , seulement, c'est hard, et pas courant dans les tutoriaux sad





2

ça commence à marcher, mais.... /* alias de la fonction GNU etendue asprintf (non standart) Cette fonction formatte une sortie dans un buffer, qui est alloué dynamiquement. Penser à 'free' le buffer quand on a finis de l'utiliser. */ int nabprintf(char *str,const char *format, ...)/*limitation, n'accepte qu'une seule balise %s pour l'instant*/ {      int str_size=1024;      int mem_size;      va_list ap,aq;      char *buffer;      /*initialisation argument 'variadique'*/            va_copy (aq ,ap);      va_end(ap);      if((buffer=(char *)malloc(str_size*sizeof(char)))==NULL)      {           fprintf(stderr,"L'allocation de memoire a echouer (%d octets demandé)\n",str_size);      }      mem_size=str_size;      while(str_size <0 || str_size>=mem_size)      {           va_copy (aq ,ap);           va_end(ap);           va_start (aq ,format);                      str_size=snprintf(buffer,mem_size,format,va_arg (aq,char*));/*là, ça marche, mais pour un seul argument*/           printf("verification:\n");           printf("format:%s\n",format);           printf("buffer:%s\n",buffer);           va_end(aq);                      if(str_size <0)           {                fprintf(stderr,"Une erreur s'est produite durant l'execution de snprintf\n");                return FALSE;           }           if(str_size>=mem_size)           {                char *ptr;                fprintf(stderr,"le resultat de snprintf est trop grand, realocation de memoire %d->%d\n",mem_size,str_size);                if((ptr=(char *)realloc(buffer,str_size*sizeof(char)))==NULL)                {                     fprintf(stderr,"L'alocation de memoire a echouer (%d octets demandé),neanmoins, le pointeur reste neanmoins intact\n",str_size);                     return FALSE;                }                else                {                     buffer=ptr;                }           }      }      return TRUE; }

j'obtiens la sortie escompté:
------------------------------------
| numero |   nom_adapt  |   clef   |
------------------------------------
|      0 |     chouette |  1321652 |
------------------------------------
|      1 |  steak hache |   986325 |
------------------------------------
|      2 | machin chose |     6325 |
------------------------------------
|      3 |       bidule |   164325 |
------------------------------------

Choisissez un adaptateur local (de 0 a 3) : 1
verification:
format: DELETE FROM adaptateurs_locaux WHERE clef=%s
buffer: DELETE FROM adaptateurs_locaux WHERE clef=986325
clef adaptateur distant effacée:986325



Le problème est que mon sprintf "fait maison" n'accepte alors plus qu'une seule balise: %s (et une seule fois en plus)

C'est plus vraiment une fonction à nombre d'argument variable.

Ya un moyen autre que parser la totalité du tableau 'aq' ?
ça pourrait pas passer avec une sorte de gros cast un peu degueu ?








3

Regarde la source de la glibc pour la fonction asprintf:
ftp://ftp.cs.univ-paris8.fr/mirrors/ftp.gnu.org/glibc

4

#usine à gaz inside#

j'ai trouvé ce que je cherchai, malheuresement, on ne peut pas bricoler,
il change la declaration façons "..." par l'utilisation de <stdarg.h>.On peut facilement passer de "..." au format defini par stdarg.h, mais j'ai pas trouvé pour faire le contraire.




.
j'ai plus qu'à faire un gros copier coller des sources. gni
dommage, j'aurai bien aimer le gerer moi meme.

5

Je n'ai pas trop compris ce que tu voulais faire précisément, mais tu peux regarder du côté de vprintf peut-être que ça t'aidera.
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »

6

Ta source utilise snprintf qui n'est pas non plus une fonction ANSI C89 / ISO C90. (C'est une fonction ISO C99.) Donc ce n'est pas bon non plus pour tes vieilles machines.
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

7

t'inquiete pas; je metrtai aussi les sources de snprintf, en esperant que ça suffise, sinon, je vais devoir trouver une autre solution, je vais pas distribuer libc.so avec mon programmewink
Surtout que c'est meme pas dit que ça suffise roll

8

Compile avec "-static"

9

merci pour ll'info.Mais je suis en periode ecole là, et ce dont on parle, c'est mon pojet entreprise, je vais reprendre ça en fevrier.