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 :

my_printf wchar_t* bug


Sujet :

C

  1. #1
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2014
    Messages
    84
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2014
    Messages : 84
    Points : 69
    Points
    69
    Par défaut my_printf wchar_t* bug
    Bonjour,

    J'essaye de refaire une partie de la fonction printf concernant les modificateur de longueurs, je bloque plus précisément sur le ' l ' avec des strings.
    Extrait de la documentation :
    (elle) La conversion entière suivante correspond à un long int ou unsigned long int, ou la conversion n suivante correspond à un pointeur sur un long int, ou la conversion c suivante correspond à un argument wint_t, ou encore la conversion s suivante correspond à un pointeur sur un wchar_t.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    wchar_t *var = va_arg(*ap, wchar_t *);
    return wconvert(var);
    Il faut savoir que je renvois toujours un char * afin que la "prochaine partie " de printf puisse manipuler la chaine (largeur, précision, attribut, ... ) bref tout le reste fonctionne. La fonction wconvert() stock le wchar_t dans un char *

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    int     main(void)
    {
           printf("%ls\n", "Bonjour");
           my_printf("%ls\n", "Bonjour"); //Fonctionne pas
     
           printf("%ls\n", L"Bonjour");
           my_printf("%ls\n", L"Bonjour"); Fonctionne
    }
    Le rendu :
    (saut de ligne uniquement \n)
    Bo (ou Bo suivi de n'importe quoi )
    Bonjour
    Bonjour
    Comment faire pour que my_printf ne se fasse pas bien piéger quand l'utilisateur envoi une chaine normal (char *) et non une L"chaine" (wchar_t *) ?
    A noté, que pour tester ce comportement, je dois compilé sans les flags (-Wall -Werror et -Wextra ), merci pour votre aide.

  2. #2
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 826
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 826
    Points : 7 123
    Points
    7 123
    Par défaut
    Comment est initialisé ap ?
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  3. #3
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2014
    Messages
    84
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2014
    Messages : 84
    Points : 69
    Points
    69
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    int my_printf(const char *format, ...)
    va_start(format, ap);
    ....
    va_end(ap);
    Je pense pas que le problème est de ce cotés car mis à part ça mon my_printf fonctionne parfaitement

    Mon seul problème est comme dit précédemment, j'aimerai que si j'envois une simple chaine de caractère mon my_printf me renvoie rien plutôt que des choses " aléatoires ". Merci Fred.

  4. #4
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 826
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 826
    Points : 7 123
    Points
    7 123
    Par défaut
    Oups, je t'ai zappé, désolé...

    Concernant ma question sur l'initialisation, je pense qu'il y a une erreur dans les paramètres de la fonction va_start, tu as dû les inverser.

    Sinon tu déclares bien ap comme un objet va_list ?
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  5. #5
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2014
    Messages
    84
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2014
    Messages : 84
    Points : 69
    Points
    69
    Par défaut
    lol pas de soucis

    Les paramètres sont dans le bonne ordre dans mon code, je l'ai ai inverser en te répondant.
    Et oui ap est un objet va_list ap;

    Je pense plus que mon problème réside dans le fait que je dois créer une fonctionne qui convertit les caractères larges en caractère multioctet ( exemple comme wcrtomb ).
    Qu'en penses-tu ?

  6. #6
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 631
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 631
    Points : 10 559
    Points
    10 559
    Par défaut
    Pour moi c'est normal que cela ne marche pas

    En char*: |B|O|N|J|O|U|R| avec |un octet|

    Mais en wchar_t*: (sous Windows avec leur UTF-16 pourri en 2 octets) |B|0|O|0|N|0|J|0|O|0|U|0|R|0| (<- en gros et en simplifié)

    Donc la fonction wconvert ne va pas prendre le caractère 'B' ou 'O', mais 'BO' ou 'NJ'

  7. #7
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
           printf("%ls\n", "Bonjour");
           my_printf("%ls\n", "Bonjour"); //Fonctionne pas
    C'est un comportement indéfini, si l'appelant de la fonction se trompe rien n'oblige la fonction à fonctionner quand même.

    Et on sait ce qui arrive quand on emploie des heuristiques de détection...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

Discussions similaires

  1. Réponses: 2
    Dernier message: 06/03/2003, 16h37
  2. Bug new build ??
    Par rgarnier dans le forum XMLRAD
    Réponses: 4
    Dernier message: 31/01/2003, 10h30

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