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 :

[Portabilité] Programme qui fonctionne sous Linux mais pas sous Windows/


Sujet :

C

  1. #1
    Membre éprouvé

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 116
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 116
    Points : 1 111
    Points
    1 111
    Par défaut [Portabilité] Programme qui fonctionne sous Linux mais pas sous Windows/
    Bonjour. J'ai un programme qui fonctionne très bien sous linux, compilé avec GCC. Avec Cygwin, rien ne va plus.

    Je voudrai savoir si ça peut être du à des caracteres interprétés différemment sous windows et linux, tels que '\r', par exemple...

    Vraiment je suis perdu.

    Voilà les différents fichiers concernés en pièce jointe.

    Quelques remarques sur le problème :
    • Je fait souvent des conversions char->unsigned char pour indexer mon tableau qui regroupe les occurences de chaque caractere. Ainsi chaque case est indexée par le code octal du caractere en question.
    • Le code binaire que j'écris est codé unsigned char par unsigned char et ensuite écrit dans le fichier de codage avec fputc(char_to_write, fp_encoded) ;.
    • En fait, je vois que le fichier binaire d'encodage est d'ors et déjà différent que le fichier encodé sous Linux. Le fichier sous linux fait 515 octets, et 511 octets avec Cygwin. Donc le résultat final ne peut pas être le même. Le problème si situe peut être dans l'encodage du fichier.
    • La table des occurences est différente sous Linux et Windows :
      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
       
      $ diff -u baudelaire.txt.htab bin/Debug/baudelaire.txt.htab
      --- baudelaire.txt.htab 2009-04-07 13:11:59.257534500 +0200
      +++ bin/Debug/baudelaire.txt.htab       2009-04-07 12:45:29.080934500 +0200
      @@ -4,6 +4,8 @@
        44  16
        45  2
        46  6
      + 59  1
      + 65  1
        67  2
        68  3
        69  11
      @@ -38,4 +40,5 @@
       121  1
       160  2
       169  10
      +174  1
       195  13
      On a trois caracteres en plus qui sont lus sous Linux, et pas sous Windows. Quésaquo ? Le morceau de code concerné par le comptage des caracteres :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
       
      unsigned char index ;
      char * istring ;
      huffman_tree leaves_tab[256] ;
      for ( i = 0 ; i < len_istring ; i++ )
      {
            index = istring[i] ; /* on incremente le compteur de 1 a chaque 
            occurence */
            leaves_tab[index].count = leaves_tab[index].count + 1 ;
      }
    • Je poste ici la fonction principale responsable, n'hésitez pas à me demander si vous voulez que je poste plus de code.

    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
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
     
    #ifndef HUFFMAN_HEADER_H_INCLUDED
        #include "huffman_header.h"
    #endif
     
    void encode_string( const char * istring, huffman_tree * huffman_index, const char * filename )
    {
        /* cette procedure prend une chaine istring en entree, l'encode a partir de l'index
        donne en argument, et ecrit le resultat de l'encodage dans le fichier filename*/
     
        FILE * fp ;
        fp = fopen(filename, "w") ;
        #ifdef DEBUG
        puts("on entre dans encode_string") ;
        #endif
        if( fp != NULL )
        {
            /* variables sur le mot binaire a encoder */
            unsigned char index ;
            unsigned char pos_bit ;
            unsigned char pos_char ;
            unsigned int j ;
     
            /* variable sur la chaine d'entree */
            unsigned int i ;
     
            /* variables sur la chaines de sortie (chaine encodee)*/
            unsigned long int size_ofile ; /* ne depasse pas la taille du fichier
            de sortie en char*/
            unsigned char obit_pos ; /* ne depasse pas 7 */
            unsigned char char_to_write ; /* octet a ecrire dans le fichier */
            unsigned char bit ;
     
            i=0 ;
            obit_pos = 0 ;
            size_ofile = 0 ;
            char_to_write = 0 ;
            while( istring[i]!='\0' )
            {
                index = istring[i] ; /* index dans la table d'encodage du caractere istring[i] */
                for ( j = 0 ; j<huffman_index[index].bit_size ; j++ )
                {
                    pos_bit = (j%CHAR_BIT) ; /* position du bit a ecrire */
                    pos_char = (j/CHAR_BIT) ; /* position de l'octet a ecrire */
                    bit = read_bit( pos_bit, huffman_index[index].bin_word[pos_char] ) ;
                    char_to_write = write_bit(bit, obit_pos , char_to_write ) ;
                    obit_pos = (obit_pos+1)%8 ;
                    if( obit_pos == 0 )
                    {
                        /* si cette valeur est un multiple de 8, on inscrit ce caractere
                                                         et on passe au suivant */
                        putc(char_to_write,fp);
                        char_to_write = 0 ;
                        size_ofile ++ ;
                    }
                }
                i = i + 1 ;
            }
            putc(char_to_write,fp) ;
     
            fclose(fp) ;
            fp=NULL ;
            #ifdef DEBUG
            puts("dans encode_string() :") ;
            printf( "la taille de la chaine initiale est de %u caracteres\n" , i ) ;
            printf( "la taille de la chaine finale est de %lu caracteres\n\n" , size_ofile+1 ) ;
            #endif
        }
        else
        {
            puts("impossible d'ouvrir le fichier dans encode_string") ;
        }
        #ifdef DEBUG
        puts("on sort de encode_string") ;
        #endif
    }
    Fichiers attachés Fichiers attachés

  2. #2
    Membre chevronné
    Homme Profil pro
    Dév. Java & C#
    Inscrit en
    Octobre 2002
    Messages
    1 414
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Dév. Java & C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2002
    Messages : 1 414
    Points : 1 996
    Points
    1 996
    Par défaut
    Bonjour,

    Une piste à suivre est que sous Windows la fin de ligne est déterminé par deux caractères CR et LF (CR CarriageReturn 0x0D et LF LineFeed 0x0A).

    Sous unixoïde, seul LF indique la fin de ligne.

    Mais sous Cygwin, on peut indiquer au système quel indicateur de fin de ligne, il faut utiliser.

  3. #3
    Membre éprouvé

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 116
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 116
    Points : 1 111
    Points
    1 111
    Par défaut
    Pour Cygwin, comment fait on pour changer le comportement, pour que je vérifie rapidement si ça change quelque chose ? Merci beaucoup. Je pense que c'est le comportement de fgets qui devrait être modifié par ce problème, mais je n'en sais trop rien. Merci beaucoup pour votre aide.

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    39
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 39
    Points : 47
    Points
    47
    Par défaut
    Bonjour !
    Je confirme que l'utilisation de gets() ou plus généralement de la lecture d'un fichier ligne par ligne pose des problèmes de portabilité... c'est essentiellement dû aux éditeurs de texte qui ajoutent les caractères de fin de ligne qu'ils veulent.

    Il y a un truc à toujours faire quand ton programme est sensible à ces problèmes, c'est d'ouvrir explicitement tes fichiers en mode binaire, en lecture comme en écriture, ainsi les opérations de lecture / écriture seront exactes à l'octet près dans tous les cas. En mode texte (je crois que c'est le mode par défaut, d'ailleurs ?), on a toujours des surprises sous certains OS...

    Donc dans ton cas tu est soumis à 2 problèmes :
    • L'édition du texte (le fichier sur lequel ton programme travaille), qui met des fins de lignes bizarres
    • L'ouverture de tes fichiers en mode texte qui implique parfois en background une gestion bizarre des opérations R/W


    Je m'excuse de n'avoir pas le temps de décortiquer ton programme maintenant pour te conseiller...

  5. #5
    Membre éprouvé

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 116
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 116
    Points : 1 111
    Points
    1 111
    Par défaut
    Bon, après moulte péripétie et interrogations, je suis tombé sur cette discussion :
    http://www.developpez.net/forums/d64...ar-26-sub-eof/

    Effectivement, j'ai cessé d'utiliser fgets et fread pour lire les fichiers caractere par caractere avec fgetc, avec des fichiers en mode binaire, et cela a complétement résolu mon problème. Tout marche très bien maintenant.

    Je vous remercie d'avoir pris le temps de m'aider.

    Cordialement,

    kromartien.

  6. #6
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par kromartien Voir le message
    Bon, après moulte péripétie et interrogations, je suis tombé sur cette discussion :
    http://www.developpez.net/forums/d64...ar-26-sub-eof/

    Effectivement, j'ai cessé d'utiliser fgets et fread pour lire les fichiers caractere par caractere avec fgetc, avec des fichiers en mode binaire, et cela a complétement résolu mon problème. Tout marche très bien maintenant.
    Si les fichiers textes proviennent d'un environnement différent du sien, on est obligé de faire comme ça.

    Le format interne des fichiers textes n'est pas portable. La tendance est quand même de s'aligner sur le format Unix (raw), qui est supporté par la plupart des éditeurs MS-DOS/Windows modernes.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [LibreOffice][Tableur] Une macro qui fonctionne sous Linux mais pas sous windows
    Par ludox62 dans le forum OpenOffice & LibreOffice
    Réponses: 3
    Dernier message: 07/01/2014, 22h26
  2. Bad_alloc sous Linux mais pas sous mac
    Par betaplus dans le forum C++
    Réponses: 4
    Dernier message: 11/03/2013, 15h03
  3. JCheckbox icones persos - Bug sous linux mais pas sous Windows
    Par Hemophilius dans le forum AWT/Swing
    Réponses: 16
    Dernier message: 04/11/2011, 16h34
  4. Script qui marche sous Linux mais pas sous Windows et vice versa
    Par tu-phat dans le forum Applications et environnements graphiques
    Réponses: 2
    Dernier message: 26/11/2009, 03h39
  5. [JMF] Code fonctionnant sous Linux mais pas sous XP
    Par Monsieur_Max dans le forum Multimédia
    Réponses: 4
    Dernier message: 25/05/2006, 19h57

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