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 :

sprintf() problème avec XP seulement


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Août 2008
    Messages
    48
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 48
    Par défaut sprintf() problème avec XP seulement
    Bonsoir à tous,

    Je fais face à un petit problème assez embêtant avec une fonction de base du C: sprintf().

    J'ai essayé le code sous Windows Vista et Windows XP. Je viens de me rendre compte aujourd'hui que sous XP, la même ligne de code ne produisait pas le même résultat.

    Pour une petite idée voilà le code. Pour info nom_fichier correspond à un wxString (je suis sous wxWidgets).

    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
     
    wxFileName fname(chemin_fichier); //Pour pouvoir récupérer nom du fichier + extension 
    wxString nom_fichier = fname.GetFullName();
    //Ici je peux afficher le nom+extension sans aucun problème
    size_t t_tempo = nom_fichier.Len(); // Taille chaine nom_fichier
    // Controle dela taille retournée = nb caractères = OK
     
    // Ces 3 lignes sont là juste pour tester
    char test[34];
    sprintf(test,"%s",nom_fichier.c_str());
    wxMessageBox(wxT(test),"chemin depuis tableau",wxOK); // Ici j'affiche bien le nom du fichier sans problème
     
    char trame_init[(int)t_tempo+34]; // Tableau pour recevoir les données avant insertion dans le tableau (+34 inclu 13 caractères pour chaque long long int et les spérateurs (|) )
    sprintf(&trame_init[4],"%lli|%lli|%i|%s",this->taille_fichier,this->start,demande_retour,nom_fichier.c_str()); // Insertion dans tableau temporaire
    wxMessageBox(wxT(&trame_init[4]),"tableau envoi",wxOK);
    // Ici en affichant la trame "composée" la dernière partie qui devrait correspondre à ma chaine (nom du fichier) est remplacée par (null). Et ce problème ne se produit que sous XP!
    Comme je viens de le noter juste au dessus, le problème intervient au niveau du sprintf() qui si je met avant des %lli etc... me met une chaine vide dans le tableau (les vérifs sont faites avant donc le problème vient bien de cette instruction précise). Théoriquement pas de débordement de mémoire, il y a même plus que nécessaire. De plus le problème se pose que sous XP. La même application exécutée sous Vista ne pose pas le problème et ne l'a jamais posé.

    Merci à ceux qui auraient une idée

    Bonne soirée à tous

  2. #2
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Par défaut
    Un problème de runtime C différent entre XP et vista probablement. Tout le monde ne semble pas d'accord sur la manière de décrire un format pour un nombre 64 bits. Certains utilisent %lld et d'autres %I64d, cela doit être ton problème.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
      printf("value using I64d: %I64d\n", value); /* for Borland BCC or Microsoft VC++ */
      printf("value using Ld:   %Ld\n", value); /* for Borland BCC */
      printf("value using lld:  %lld\n", value); /* for gcc */
      printf("value using I64x: %016I64x(hex)\n", value);/* for Borland BCC or Microsoft VC++ */
      printf("value using Lx:   %016Lx(hex)\n", value);/* for Borland BCC */
      printf("value using llx:  %016llx(hex)\n", value); /* for gcc */
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Août 2008
    Messages
    48
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 48
    Par défaut
    Bonsoir et merci d'avoir pris le temps de répondre.

    Mais le problème c'est que lorsque j'affiche pas par pas, la trame composée qui se trouve dans le tableau de caractères est 34567|0|0|(null)

    Donc je récupère bien mes long long int (qui ici correspondent à des integer on est d'accord, mais il peuvent contenir des valeurs qui tiennent sur 64 bits). C'est uniquement la chaine ( nom_fichier.c_str() ) qui est remplacée par (null) sous XP. Si le problème venait des long long int il n'apparaitraient pas dans le tableau avec XP non?

    Merci

  4. #4
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Par défaut
    Admettons que cela soit un problème d'interprétation %lld/%I64d

    lorsque tu empiles tes parametres pour le sprintf, tu empiles 2 nombres 64 bits + 1 nombre 32 bits + 1 pointeur

    le sprintf se trompe avec le format et prend %lld (ou %lli, c'est pareil) pour un format 32 bits. Avec "%lli|%lli|%i|%s", il dépile 2 nombres 32 bits + 1 nombres 32 bits + 1 pointeur. Le pointeur dépilé se trouve être le poid faible ou fort de ton 2eme nombre 64 bits et peut être que ce résidus de nombre 64 bits vaut 0 interprété comme NULL

    Une explication qui vaut ce qu'elle vaut
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  5. #5
    Membre Expert
    Avatar de Gruik
    Profil pro
    Développeur Web
    Inscrit en
    Juillet 2003
    Messages
    1 566
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juillet 2003
    Messages : 1 566
    Par défaut
    Salut,

    peut etre plutot un probleme avec wxWidget au niveau de l'objet wxString et sa methode c_str()?

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Août 2008
    Messages
    48
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 48
    Par défaut
    Bonsoir,
    EDIT: Ce qui suit concerne la remarque sur wxString

    Et bien justement je ne pense pas parce que j'ai utilisé des messageBox pour vérifier celà (je les ai peut être enlevé dans le code ci-dessus).

    Et dans le premier sprintf() j'utilise bien nom_fichier.c_str() pour placer ma chaine dans le tableau et lorsque je l'affiche il contient bien la chaine.
    Donc je ne pense pas que le problème vienne de là.

    Assez spécial ce bug. Surtout que malgré tous les tests on ne s'en est rendu compte qu'aujourd'hui (on avait déjà eu le bug mais on avait pas pensé que ca venait de XP parce qu'on était encore en plein développement).

    Merci à vous

    EDIT: Réponse à ram-0000
    Peut être pour l'interpretation des %lld en 32 bits mais dans mon cas les valeurs sont "codables" sur 32 bits donc si sprintf() les met sur 32 bits pas de soucis de ce côté là. De plus le (null) se trouve après un pipe (|) donc je ne vois pas comment cela pourrait être la suite du long long int vu que le pipe est un caractère et se trouve avant, non?
    Je me trompe peut être, je ne sais pas.

    Mais du coup je ne sais pas trop comment résoudre cela.

    Merci

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Quel compilo utilises-tu?
    C'est important, car ils n'utilisent pas la même version du runtime C, et les versions les plus vieilles ne comprennent pas le spécificateur de tailile ll (ne comprenant que I64).
    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.

  8. #8
    Membre averti
    Profil pro
    Inscrit en
    Août 2008
    Messages
    48
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 48
    Par défaut
    Bonjour,

    J'utilise MinGw 3.4.5. En remplaçant par I64d et après 2 tests cela à l'air de fonctionner sur XP, mais à voir avec des tests plus poussés (je n'ai pas moi même XP sur mon PC portable).

    Une autre question. Ce problème de compatibilité doit aussi se poser avec d'autres fonctions? Je pense notamment à sscanf(). Dois je remplacer dans celle-ci aussi mes %lli par %I64d?
    Et pour la déclaration de mes entiers sur 64 bits je peux toujours utiliser long long int? Ou cela aussi pose problème (sous XP j'entends).

    Merci à vous.

  9. #9
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Par défaut
    Effectivement, je pense que tu risques d'avoir exactement le même problème avec toute les fonction *printf() et toutes les fonction *scanf(). Pas cool hein
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

Discussions similaires

  1. Problème avec sprintf
    Par latitude38 dans le forum Débuter
    Réponses: 23
    Dernier message: 16/04/2010, 11h19
  2. Problème avec sprintf
    Par snake264 dans le forum C++
    Réponses: 10
    Dernier message: 20/04/2008, 17h12
  3. probléme avec sprintf() sous linux
    Par moooona dans le forum C++
    Réponses: 5
    Dernier message: 11/04/2008, 01h48
  4. Problème avec sprintf
    Par LinuxUser dans le forum C
    Réponses: 9
    Dernier message: 18/05/2007, 15h34
  5. Problème avec la mémoire virtuelle
    Par Anonymous dans le forum CORBA
    Réponses: 13
    Dernier message: 16/04/2002, 16h10

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