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

GTK+ avec C & C++ Discussion :

Affichage de chaine de caractères et différence de comportement linux/win32


Sujet :

GTK+ avec C & C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Chercheur
    Inscrit en
    Mars 2009
    Messages
    61
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France

    Informations professionnelles :
    Activité : Chercheur

    Informations forums :
    Inscription : Mars 2009
    Messages : 61
    Par défaut Affichage de chaine de caractères et différence de comportement linux/win32
    Bonjour/bonsoir à tous/toutes,
    une petite question pour essayer de comprendre une différence
    de comportement entre mon programme Gtk+ compilé sous Vista (Codeblocks) et sous ma bonne Fedora.
    Il m'est tout d'abord important de préciser, que sous Linux comme sous Windows, je n'ai aucune erreur 'fatale' à l'exécution ... mais mais mais ...
    Avant d'aller plus loin, mon programme est un programme d'analyse scientifique (dispo ici http://isaacs.sourceforge.net),
    à un certain point durant l'exécution je demande l'affichage dans un Gtk_Text_View du résultat d'un calcul,
    l'affichage diffère sous Win32 et Linux ... je m'excuse par avance de la longueur du texte à venir ...

    1) Résultat sous Linux (affichage Ok)
    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
     
    Shortest path ring statistics:
     
     Average number of rings per configuration: 115.900000 +/- 24.973097
     Average number of rings with n > 20 nodes which potentially exist: 135.800000 +/- 26.469269
     n     Rc(n)    Rc[All](n)    +/-       Pn(n)       +/-       Pmax(n)     +/-       Pmin(n)     +/-
     3   0.004651   0.004651   0.003562   0.010853   0.008130   0.488095   0.155371   1.000000   0.000000
     4   0.083333   0.083333   0.015205   0.295736   0.040199   0.508681   0.075866   0.996369   0.008366
     5   0.004651   0.004651   0.002451   0.022093   0.011122   0.547619   0.082685   0.911111   0.145297
     6   0.057364   0.057364   0.013770   0.229070   0.040752   0.629735   0.067917   0.666030   0.105880
     7   0.001163   0.001163   0.002616   0.006202   0.013201   0.619048   0.067344   0.706349   0.213254
     8   0.030233   0.030233   0.007029   0.117054   0.031794   0.582700   0.110923   0.469954   0.112416
     9   0.004651   0.004651   0.005420   0.018992   0.023216   0.725725   0.200212   0.426149   0.206935
    10   0.018992   0.018992   0.012318   0.066279   0.033911   0.559826   0.186853   0.344088   0.113461
    11   0.001163   0.001163   0.002616   0.007752   0.016444   0.661616   0.164277   0.494949   0.071425
    12   0.053101   0.053101   0.023474   0.116279   0.041060   0.666946   0.113125   0.390984   0.139641
    13   0.001550   0.001550   0.003269   0.001550   0.003269   1.000000   0.000000   0.000000   0.000000
    14   0.044961   0.044961   0.030311   0.069767   0.046296   0.767157   0.125960   0.284305   0.094722
    15   0.012791   0.012791   0.009503   0.015891   0.015871   0.521368   0.260955   0.110256   0.216445
    16   0.032171   0.032171   0.029237   0.054651   0.044248   0.648796   0.088311   0.195941   0.133427
    17   0.005814   0.005814   0.007806   0.005814   0.007589   0.866667   0.217307   0.000000   0.000000
    18   0.056977   0.056977   0.041103   0.026744   0.020627   0.878171   0.153111   0.039583   0.098214
    19   0.008915   0.008915   0.010971   0.007752   0.015504   0.933333   0.149071   0.107692   0.215385
    20   0.026744   0.026744   0.014894   0.045736   0.030943   1.000000   0.000000   0.280113   0.123251
    1) Résultat sous Win32 (affichage pas Ok du tout)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Shortest path ring statistics:
     
     Average number of rings per configuration: 115.900000 +/- 24.973097
     Average number of rings with n > 20 nodes which potentially exist: 135.800000 +/- 26.469269
     n     Rc(n)    Rc[All](n)    +/-       Pn(n)       +/-       Pmax(n)     +/-       Pmin(n)     +/-
     3   0.004651   0.004651   0.003562   0.010853   0.008130   0.488095   0.155371   1.000000   0.000000
     4   0.083333   0.083333   0.015205   0.295736   0.040199   0.508681   0.075866   0.996369   0.008366
     5   0.004651   0.004651   0.002451   0.022093   0.011122   0.547619   0.082685   0.911111   0.145297
     6   0.057364   0.057364   0.013770   0.229070   0.040752   0.629735   0.067917   0.666030   0.105880
     7   0.001163   0.001163   0.002616   0.006202   0.013201   0.619048   0.067344   0.706349   0.213254
     8   0.030233   0.030233   0.007029   0.117054   0.031794   0.582700   0.110923   0.469954   0.112416
     9   0.004651   0.004651   0.005420   0.018992   0.023216   0.725725   0.200212   0.426149   0.206935
    10   0.018992
    Pour faire simple sous Win32 de nombreuses informations qui devraient être affichées ne le sont pas (arrêt de l'affichage à la 10 ligne sur 20 ... )
    et je ne sais pas pourquoi ... voici mon code (je l'ai raccourci un peu pour ce message)

    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
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    void printrings_ (int * idnodes,  int * nodes, double nc[ringsize*2], double pna[ringsize*2],
                     double rmax[ringsize*2], double rmin[ringsize*2],
                     double ectrc[ringsize*2], double ectpna[ringsize*2],
                     double ectmax[ringsize*2], double ectmin[ringsize*2],
                     double * rpstep, double * ectrpst, double * nampat, double * ectampat)
    {
      int i, j;
      char * value;
      char * nelt;
      char ra[22]=" n     Rc(n)    Rc[";
      char rb[36]="](n)   Pn(n)     Pmax(n)    Pmin(n)";
      char rc[78]="](n)    +/-       Pn(n)       +/-       Pmax(n)     +/-       Pmin(n)     +/-";
      char re[20]=" ring statistics:\n";
      char rf[4]="   ";
      char rg[2]=" ";
      char rh[35]=" Average number of rings with n > ";
      char ri[33]=" nodes which potentially exist: ";
      char rj[6]=" +/- ";
      char rk[45]=" Average number of rings per configuration: ";
      char rd[42]=" * only ABAB rings have been considered\n";
      char rl[47]=" * homopolar bonds can not shorten the rings\n";
      GtkWidget * info;
      GtkTextBuffer * buffer = NULL;
      GtkTextIter bStart;
      GtkTextIter bEnd;
      size_t rtot=10;
      char * ritot;
      char * tritot;
     
      j = * idnodes;
      j = j-1;
      rtot+=strlen(retl);
    // un grand passage dans lequel je prépare la taille de mémoire à allouer ..
    // une fois cela fait j'alloue la mémoire nécessaire ...
      ritot = g_malloc(rtot*sizeof*ritot);
    /// puis je copie le tout dans ma chaine de caractères 
      strcpy(ritot,retl);
      strcat(ritot,trc[search]);
     ...
    // Enfin je veux afficher le tout, en prenant des précautions
      tritot = g_malloc(rtot*sizeof*tritot);
    #ifdef G_OS_WIN32
      wsprintf (tritot, "%s", ritot);
    #else
      snprintf (tritot, rtot, "%s", ritot);
    #endif
      g_free(ritot);
      g_print("%s", tritot);
      info = (GtkWidget *) gtk_builder_get_object (BuilderGtk, "TextInfo");
      buffer=gtk_text_view_get_buffer(GTK_TEXT_VIEW(info));
      gtk_text_buffer_get_start_iter (buffer, &bStart);
      gtk_text_buffer_get_end_iter (buffer, &bEnd);
      gtk_text_buffer_insert (buffer, &bEnd, tritot, -1);
      gtk_text_view_set_buffer (GTK_TEXT_VIEW(info), buffer);
      g_free(tritot);
    }
    Le code précédent, plus précisément la partie finale donne les résultats présentés plus haut respectivement sous Linux et Win32.

    Il m'est possible de corriger le tire et d'obtenir un affichage correct sous Win32 avec les changements suivants:
    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
     
    //  tritot = g_malloc(rtot*sizeof*tritot);
    //#ifdef G_OS_WIN32
    //  wsprintf (tritot, "%s", ritot);
    //#else
    //  snprintf (tritot, rtot, "%s", ritot);
    //#endif
    //  g_free(ritot);
      g_print("%s", ritot);
      info = (GtkWidget *) gtk_builder_get_object (BuilderGtk, "TextInfo");
      buffer=gtk_text_view_get_buffer(GTK_TEXT_VIEW(info));
      gtk_text_buffer_get_start_iter (buffer, &bStart);
      gtk_text_buffer_get_end_iter (buffer, &bEnd);
      gtk_text_buffer_insert (buffer, &bEnd, ritot, -1);
      gtk_text_view_set_buffer (GTK_TEXT_VIEW(info), buffer);
      g_free(ritot);
    Toutes vos lumières sont les bienvenues, je ne suis pas un grand programmeur et j'aimerais bien comprendre le pourquoi du comment ... merci d'avance !

  2. #2
    Membre Expert
    Homme Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 259
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 259
    Par défaut
    Tous ces mallocs, strncpy, ... font un peu peur, je te recommanderais d'utiliser g_strdup et g_strdup_printf, g_str_concat, ... au maximum, ça t'évite de gérer les tailles d'allocation mémoire toi même (et donc ça limite les risques d'erreur)

  3. #3
    Membre émérite
    Inscrit en
    Avril 2007
    Messages
    667
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Avril 2007
    Messages : 667
    Par défaut
    Salut,

    Tu ne verifie aucun retour de malloc(), il suffit que ta machine sous windows manque de memoire et tu as ton explication

    Ensuite, je ne comprends pas vraiment la difference entre ritot et tritot, tu alloues la meme quantite de memoire puis copies le contenue de ritot dans tritot...

    Et enfin, j'ai telecharge les sources pour lire le code en entier et je rejoins teuf13, tu abuses vraiment du malloc, strcat, strcpy...
    Ce serait plus lisible d'utiliser snprintf et donc plus facile d'identifier les bugs.
    Par exemple tu peux remplacer
    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
          value=g_strdup_printf("%2d",i+1);
          rtot+=strlen(value);
          g_free(value);
          rtot+=strlen(rf);
          value=g_strdup_printf("%lf",nc[i]/natomes);
          rtot+=strlen(value);
          g_free(value);
          rtot+=strlen(rf);
          value=g_strdup_printf("%lf",nc[i]/(* nodes));
          rtot+=strlen(value);
          g_free(value);
          rtot+=strlen(rf);
          value=g_strdup_printf("%lf",pna[i]/(* nodes));
          rtot+=strlen(value);
          g_free(value);
          rtot+=strlen(rf);
          value=g_strdup_printf("%lf",rmax[i]);
          rtot+=strlen(value);
          g_free(value);
          rtot+=strlen(rf);
          value=g_strdup_printf("%lf",rmin[i]);
          rtot+=strlen(value);
          g_free(value);
    par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
          char buf[1024];
          snprintf(buf, 1024, "%2d%lf%lf%lf%lf%lf", i+1,nc[i]/natomes,pna[i]/(* nodes), pna[i]/(* nodes),rmax[i], rmin[i]);
     rtot+=strlen(buf);
    Deuxieme exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
          value=g_strdup_printf("%d",i+1);
          strcat(ritot,value);
          g_free(value);
          strcat(ritot, rf);
          value=g_strdup_printf("%lf",nc[i]/natomes);
          strcat(ritot,value);
          g_free(value);
    vs
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sprintf(ritot, "%d%s%lf", i+1, rf, nc[i]/natomes);

  4. #4
    Membre Expert
    Homme Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 259
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 259
    Par défaut
    Citation Envoyé par tonton fred Voir le message
    Et enfin, j'ai telecharge les sources pour lire le code en entier et je rejoins teuf13, tu abuses vraiment du malloc, strcat, strcpy...
    Ce serait plus lisible d'utiliser snprintf et donc plus facile d'identifier les bugs.
    Par pitié, non! Pas de s.printf, c'est vraiment trop source d'erreur!

    Citation Envoyé par tonton fred Voir le message

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
          char buf[1024];
          snprintf(buf, 1024, "%2d%lf%lf%lf%lf%lf", i+1,nc[i]/natomes,pna[i]/(* nodes), pna[i]/(* nodes),rmax[i], rmin[i]);
     rtot+=strlen(buf);
    Il vaut beaucoup mieux utiliser
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
        char *buf =  g_strdup_printf("%2d%lf%lf%lf%lf%lf", i+1,nc[i]/natomes,pna[i]/(* nodes), pna[i]/(* nodes),rmax[i], rmin[i]);
    Deuxieme exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
          value=g_strdup_printf("%d",i+1);
          strcat(ritot,value);
          g_free(value);
          strcat(ritot, rf);
          value=g_strdup_printf("%lf",nc[i]/natomes);
          strcat(ritot,value);
          g_free(value);
    vs
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sprintf(ritot, "%d%s%lf", i+1, rf, nc[i]/natomes);
    Non, il vaut beaucoup mieux l'écrire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ritot = g_strdup_printf ("%s%d%s%lf", i+1, ritot, rf, nc[i]/natomes);
    (si ritot pointe sur de la mémoire malloc-ée, il faut passer par une variable intermédiaire pour libérer la mémoire utilisée)

  5. #5
    Membre confirmé
    Homme Profil pro
    Chercheur
    Inscrit en
    Mars 2009
    Messages
    61
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France

    Informations professionnelles :
    Activité : Chercheur

    Informations forums :
    Inscription : Mars 2009
    Messages : 61
    Par défaut Merci !
    Merci pour tout, j'ai besoin d'être éduqué sur la bonne manière
    d'afficher des chaînes de caractères en langage C ... je vais
    corriger mes erreurs ... n'hésitez pas à m'en apprendre
    d'avantage

  6. #6
    Membre émérite
    Inscrit en
    Avril 2007
    Messages
    667
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Avril 2007
    Messages : 667
    Par défaut
    Citation Envoyé par teuf13 Voir le message
    Par pitié, non! Pas de s.printf, c'est vraiment trop source d'erreur!
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    char buf[1024];
          snprintf(buf, 1024, "%2d%lf%lf%lf%lf%lf", i+1,nc[i]/natomes,pna[i]/(* nodes), pna[i]/(* nodes),rmax[i], rmin[i]);
    Il vaut beaucoup mieux utiliser
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
        char *buf =  g_strdup_printf("%2d%lf%lf%lf%lf%lf", i+1,nc[i]/natomes,pna[i]/(* nodes), pna[i]/(* nodes),rmax[i], rmin[i]);
    Dans le cas present, il n'y a pas de difference de syntaxe entre snprintf et g_strdup_printf, sauf que snprintf permet de travailler sur un tableau statique alors que g_strdup_printf oblige a utiliser un tableau dynamique:
    - strdup alloue de la memoire qu'il ne faut pas oublier de liberer
    - il faut gerer les cas ou l'allocation echoue ce qui n'est que tres rarement simple (annuler le traitement et continuer avec la valeur suivante? travailler sur des donnees que l'on sait fausses ou tronquees? crasher brutalement?).

    Dans le cas present, les tableaux sont internes a la fonction et de taille modeste (20 lignes, 10 colonnes) donc je ne vois aucun interet a passer par des tableaux dynamiques.

    Edit:
    Citation Envoyé par liberforce Voir le message
    Tu te trompes, g_malloc fait une assertion quand il n'y a plus de mémoire. L'équivalent à malloc est g_try_malloc, qui lui renvoie NULL s'il n'a pas réussi à allouer la mémoire demandée. Et je confirme ce que dit teuf, il faut utiliser g_strdup_printf qui est beaucoup plus simple à utiliser.
    g_strdup_printf peut echouer il me semble non?

  7. #7
    Membre Expert
    Homme Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 259
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 259
    Par défaut
    [quote=tonton fred;5128997]Dans le cas present, il n'y a pas de difference de syntaxe entre snprintf et g_strdup_printf, sauf que snprintf permet de travailler sur un tableau statique alors que g_strdup_printf oblige a utiliser un tableau dynamique:
    - strdup alloue de la memoire qu'il ne faut pas oublier de liberer

    Citation Envoyé par tonton fred Voir le message
    - il faut gerer les cas ou l'allocation echoue ce qui n'est que tres rarement simple (annuler le traitement et continuer avec la valeur suivante? travailler sur des donnees que l'on sait fausses ou tronquees? crasher brutalement?).
    Nope, cf la remarque de liberforce, la glib arrêtera de toute façon tout si tu n'as plus de mémoire

    Dans le cas present, les tableaux sont internes a la fonction et de taille modeste (20 lignes, 10 colonnes) donc je ne vois aucun interet a passer par des tableaux dynamiques.
    Il y a un énorme intérêt, tu n'as pas besoin de compter, compter et recompter pour allouer statiquement un buffer suffisamment grand, et ça, les gens se trompent tout le temps. Avec g_strdup_printf, pas d'erreur possible, donc vive g_strdup_printf. Oui, il y a quelques fois où snprintf peut être mieux, mais je préfère largement ne pas me prendre la tête et prendre une fonction qui ne va pas m'ajouter un bug obscur de corruption de mémoire parce que j'ai fait ue petite erreur dans une addition.

  8. #8
    Modérateur

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2009
    Messages
    1 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 395
    Par défaut
    Citation Envoyé par tonton fred Voir le message
    Tu ne verifie aucun retour de malloc(), il suffit que ta machine sous windows manque de memoire et tu as ton explication
    Tu te trompes, g_malloc fait une assertion quand il n'y a plus de mémoire. L'équivalent à malloc est g_try_malloc, qui lui renvoie NULL s'il n'a pas réussi à allouer la mémoire demandée. Et je confirme ce que dit teuf, il faut utiliser g_strdup_printf qui est beaucoup plus simple à utiliser.

Discussions similaires

  1. sed - différence de comportement linux/AIX
    Par jack-ft dans le forum Shell et commandes POSIX
    Réponses: 7
    Dernier message: 02/07/2012, 17h12
  2. Affichage de chaine de caractère crypté
    Par Sephiroth.WIN dans le forum Sécurité
    Réponses: 1
    Dernier message: 25/06/2009, 22h26
  3. affichage de chaines de caractères
    Par yasinfo dans le forum Débuter avec Java
    Réponses: 7
    Dernier message: 04/04/2008, 19h10
  4. Affichage de chaine de caractére dans une Applet
    Par ibtbsoft dans le forum Applets
    Réponses: 3
    Dernier message: 03/12/2007, 01h51
  5. format affichage des chaines de caractères
    Par gorgonite dans le forum Langage
    Réponses: 3
    Dernier message: 10/05/2007, 22h14

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