IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Un printf différent


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Par défaut Un printf différent
    Bonjour !


    Ca fait un bail que j'ai plus posé de question mais là je suis devant un petit problème sans doute de conception de l'époque mais pas trouvé réellement d'alternative.

    J'ai créé il y a bien 2 ans un objet String perso "C_Str" et je vais reprendre un peu le développement pour l'améliorer et voir peut-être même le compléter. Dans cet objet se trouve des fonctions de la famille printf genre:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    int C_Str_printf (C_Str * const format, ...)
    {
       int ret = -1;
       va_list params;
     
     
       if (format != NULL && format->sz_string != NULL && format->len > 0)
       {
          va_start (params, format->sz_string);
          ret = vprintf (format->sz_string, params);
          va_end (params);
       }
     
     
       return ret;
    }
    L'objet de base est le suivant:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    struct _C_Str
    {
       char * sz_string;
       size_t len;
    };
    Mon problème viens de la liste variable. Je sais que
    La macro va_arg se développe en une expression qui a le type et la valeur de l'argument suivant de l'appel.
    hors ici dans l'ouverture de la liste
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    va_start (params, format->sz_string);
    le type n'est plus le même vu que le but est d'utiliser la chaîne contenu dans l'objet et non pas l'objet lui même et que pour une question de sécurité au niveau de la chaîne, seul l'objet peut être passé en argument aux fonctions car c'est un objet opaque.

    Le compilateur me dit
    D:\Programmation\Modules\C_Str\v2.3\c_str.c|765|warning: second parameter of `va_start' not last named argument|
    ce qui est tout à fait normal Bien sûr cela fonctionne quand même, testé sur la même machine, windows et linux mais est-ce que ca peut engendrer tôt ou tard chez d'autre personnes des comportements indéterminés ca, ca reste à savoir

    Enfin bref après cette présentation précise, quelles seraient les solutions, en tenant compte que le but final est d'avoir des fonctions comme printf (et les autres de la même famille) jusqu'au niveau de leur utilisation et tout en étant des fonction variadiques ?


    Merci pour vos suggestions/conseils
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  2. #2
    Membre Expert Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Par défaut
    Je n'ai pas du comprendre ton problème car que je comprend toujours pas pourquoi tu fais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    va_start (params, format->sz_string);
    au lieu de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    va_start (params, format);

  3. #3
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Par défaut
    Citation Envoyé par nicolas.sitbon Voir le message
    Je n'ai pas du comprendre ton problème car que je comprend toujours pas pourquoi tu fais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    va_start (params, format->sz_string);
    au lieu de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    va_start (params, format);
    Oui en effet tu n'as pas compris mon problème

    Ce que tu m'a proposé plus haut ne fonctionne pour la simple et bonne raison évoquée dans mon premier post, est que ici format représente mon objet String et non la chaîne qui est le memebre sz_string de l'objet en question.

    Ici le but est de travailler sur la chaîne donc je suis obligé de faire format->sz_string étant donné que le compilateur ne va pas deviner ce que je veux faire (quoique, ca serait pas mal ca )
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  4. #4
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 738
    Par défaut
    D'après ce que j'ai compris le c_str_printf prend est un printf dans lequel les différents char* ont été remplacés par des c_str.
    Et peut être pas seulement le premier argument => il faut peut être analyser le contenu du fmt pour traiter les éventuels %s comme c_str?
    Pour le reste, je pense comme nicolas.sitbon:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
          va_start (params, format);  // a-t-on le choix???
    ce qui n'empêche pas de passer le "format->sz_string" à vsxxx
    non?
    -W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  5. #5
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Je suis de l'avis de nicolas.sitbon et wiztricks :
    Ceci "semble" marcher (j'ai légèrement modifié C_Str pour tester)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    typedef struct _C_Str
    {
       char  sz_string[256];
       size_t len;
    }C_Str;
    //---------------------------------------------------------------------------
    int C_Str_printf (C_Str * const format, ...)
    {
       int ret = -1;
       va_list params;
     
     
       if (format != NULL && format->sz_string != NULL && format->len > 0)
       {
          va_start (params, format);
          ret = vprintf (format->sz_string, params);
          va_end (params);
       }
       return ret;
    }
    //---------------------------------------------------------------------------
    int main(void)
    {
      char fr[] = "%d%s" ;
      int i;
      C_Str frmt;
      strcpy(frmt.sz_string,fr);
      frmt.len = strlen(fr);
      i = C_Str_printf(&frmt, 18,"azerty");
      return 0;
    }
    alors qu'avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    va_start (params, format->sz_string);
    ça plante.

    Reste le problème d'avoir comme argument un c_str comme le signale wiztricks

  6. #6
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Par défaut
    Citation Envoyé par Franck.H Voir le message
    Ce que tu m'a proposé plus haut ne fonctionne pour la simple et bonne raison évoquée dans mon premier post, est que ici format représente mon objet String et non la chaîne qui est le memebre sz_string de l'objet en question.

    Ici le but est de travailler sur la chaîne donc je suis obligé de faire format->sz_string étant donné que le compilateur ne va pas deviner ce que je veux faire (quoique, ca serait pas mal ca )
    Je pense qu'il y a une incompréhension sur les paramètres à passer à va_start(). Il n'attend pas du tout la chaîne de formatage (qui peut très bien ne pas exister du tout par ailleurs, l'ellipse n'est pa réservé à des utilisation du style de printf() ou de scanf() bien que ce soit l'usage le plus fréquent) mais le paramètre précédent l'ellipse.

  7. #7
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    D'après ce que j'ai compris le c_str_printf prend est un printf dans lequel les différents char* ont été remplacés par des c_str.
    Et peut être pas seulement le premier argument => il faut peut être analyser le contenu du fmt pour traiter les éventuels %s comme c_str?
    C'est une des raisons pour laquelle je reprend le développement de ces fonctions car elles sont inachevées et d'ailleurs je ne sais pas encore comment déterminer si un argument de la liste variable est par exemple une chaîne ou un objet C_Str dans quel cas il va falloir accéder à sa chaîne, tout est faisable mais je crois que j'ai un petit problème, je ne sais pas encore comment faire

    Mettre peut-être en place une balise de type %s mais correspondant plutôt à mon objet string (%S ? ) et parcourir la liste tout en en recréant une plus viable (ou réussir à déterminer si on tombe sur %s que l'argument correspondant est une chaîne ou un objet dont lequel il faudra extraire la chaîne) tout en passant cette fois les chaînes des objets au lieu des objets eux-même. Je reste ouvert à toutes suggestions

    Cette solution qui est plutôt sympa du point de vue théorie peut être un peu casse-tête à mettre en place d'autant plus qu'un objet de ce type ne possède pas réellement de type comme si on était en OO à moins d'un tour de force que je ne connais pas

    Citation Envoyé par wiztricks Voir le message
    Pour le reste, je pense comme nicolas.sitbon:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
          va_start (params, format);  // a-t-on le choix???
    ce qui n'empêche pas de passer le "format->sz_string" à vsxxx
    non?
    -W
    Oui c'était effectivement une grossière erreur de ma part
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  8. #8
    Membre Expert Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Par défaut
    Pour continuer le débat, je dirais que la seule manière de faire ça de façon portable serait de recoder intégralement les fonctions des familles printf() et scanf(), c'est fastidieux, autant améliorer le travail déjà fournis par les autres, pour ma part j'aime bien la bibliothèque trio, ou si la portabilité n'est pas un soucis mais j'en doute : http://www.gnu.org/s/libc/manual/htm...ng-Printf.html.
    A toi de voir de Franck, j'opterai personnellement pour trio qui reste une implémentation en C ANSI, donc très portable et facilement extensible.
    Cordialement.

Discussions similaires

  1. Comportement de printf différent en local et distant
    Par xion1024 dans le forum Langage
    Réponses: 2
    Dernier message: 02/04/2008, 12h05
  2. 2 printf identiques affichent resultats différents
    Par Margatthieu dans le forum C
    Réponses: 6
    Dernier message: 13/01/2008, 13h59
  3. Simulation de transmission de paquet entre différent réseaux
    Par MelloW dans le forum Développement
    Réponses: 2
    Dernier message: 12/07/2002, 19h51
  4. fonction printf
    Par ydeleage dans le forum C
    Réponses: 7
    Dernier message: 30/05/2002, 11h24
  5. Réponses: 2
    Dernier message: 17/05/2002, 20h37

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo