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 :

[encodage] Lecture/écriture dans des fichiers


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre émérite Avatar de Ceylo
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2007
    Messages
    1 216
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 216
    Par défaut [encodage] Lecture/écriture dans des fichiers
    Bonjour à tous,

    Actuellement j'ai mis au point un programme qui me permet de colorier mon code afin de l'afficher sur une page web (pour un petit exemple, voir sur http://spootnikdev.dyndns.org/progra...c=AGLContext.c (c'est un site perso hébergé sur mon Mac que je laisse à disposition de 9h à 22h minimum ->heure de France)). Pour la 1e version de ce logiciel, j'ai utilisé une bibliothèque sépcifique à mon système (Mac OS X) et qui gère donc elle-même l'encodage.

    Je cherche maintenant à obtenir le même programme, mais cette fois ci en utilisant des fichiers d'en-tête génériques (stdlib.h, stdio.h et string.h).

    J'ai donc adapté mon code à ces "headers". Le programme fonctionne sans erreur apparente, mais lorsque je regarde le fichier coloré (en HTML), j'obtiens plein de symboles étranges, alors que d'autres parties apparaissent clairement.

    cÿýèoÿýèmÿýèpÿýèlÿýèeÿýètÿýèeÿýèlÿýèyÿýèd.\n");
    break;
    }
    break;
    Je pense que le problème vient de mes méthodes d'écriture/lecture dans mes fichiers (fichier de code comme source et fichier HTML comme destination).

    Mon code n'est peut-être pas très "propre"

    Voici ma méthode de lecture (la fonction strFromStrings() est décrite plus bas) :

    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
     
    #define TAILLE_MAX 4096
     
    char *readFromFile(const char *path){
         char *cData = "";
         FILE* fichier = NULL;
         char chaine[4096] = "";
     
         fichier = fopen(path, "r");
     
         if (fichier != NULL){
              while (fgets(chaine, TAILLE_MAX, fichier) != NULL){
                   cData = strFromStrings(cData, chaine);
              }
              fclose(fichier);
         } else {
              return NULL;
         }
     
         return cData;
    }
    et ma méthode d'écriture :

    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
     
    unsigned char writeToFile(const char *path, const char *data){
         FILE* fichier = NULL;
     
        fichier = fopen(path, "w");
     
         if (fichier != NULL){
              unsigned int lgt = strlen(data);
              unsigned int i = 0;
              for (i = 0;i < lgt;i++){
                   fputc( data[i], fichier);
              }
              fclose(fichier);
              return 1;
         } else {
              return NULL;
         }
    }
    Ma fonction writeToFile() renvoie NULL en cas d'erreur lors de l'écriture.

    Mais à part ces méthodes simples de lecture/écriture, je ne sais pas du tout comment gérer l'encodage (si le problème est bien l'encodage). Je sais qu'il existe la bibliothèque libiconv, mais je n'arrive pas du tout à m'en servir.


    J'aimerais aussi avoir vos avis sur un nettoyage du code que j'utilise pour assembler des chaines de caractère. Je suis sûr qu'il y a plus propre

    Voici mon code d'assemblage (à la barbare):

    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
     
    #include <stdlib.h>
     
    char *strFromStrings(char *str1, char *str2){
         unsigned int len1, len2;
         len1 = strlen(str1);
         len2 = strlen(str2);
     
         char *strCat = malloc(sizeof(char) * (len1 + len2));
         unsigned long i = 0;
         for(i = 0; i < len1;i++){
              strCat[i] = str1[i];
         }
         for(;i < (len1 + len2);i++){
              strCat[i] = str2[i - len1];
         }
     
         return strCat;
    }
    Pour info, il n'y a eu aucun bug de mémoire lorsque j'ai testé mon programme.

    Merci à tous

  2. #2
    Expert éminent
    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
    Par défaut
    Citation Envoyé par Spootnik-Dev
    Pour info, il n'y a eu aucun bug de mémoire lorsque j'ai testé mon programme.
    Hum. Est-tu bien conscient qu'une chaine est terminée par un 0 ? Parce que quand je vois ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
         unsigned int len1, len2;
         len1 = strlen(str1);
         len2 = strlen(str2);
         char *strCat = malloc(sizeof(char) * (len1 + len2));
    j'ai peur...

    D'autre part, pourquoi tu n'utilises pas strcpy() et strcat() au lieu de ces boucles ?

    Voici ton code mis au point (chargement).

    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
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
     
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
     
    #define TAILLE_MAX 4096
     
    static char *strFromStrings (char *str1, char *const str2)
    {
       char *strCat = NULL;
       size_t len1 = (str1 == NULL) ? 0 : strlen (str1);
     
       void *tmp = realloc (str1, len1 + strlen (str2) + 1);
     
       if (tmp != NULL)
       {
          strCat = tmp;
          if (str1 == NULL)
          {
             strcpy (strCat, "");
          }
          strcat (strCat, str2);
       }
       else
       {
          free (strCat), strCat = NULL;
       }
     
       return strCat;
    }
     
    static char *readFromFile (const char *path)
    {
       char *cData = NULL;
     
       FILE *fichier = fopen (path, "r");
     
       if (fichier != NULL)
       {
          char chaine[TAILLE_MAX] = "";
     
          while (fgets (chaine, TAILLE_MAX, fichier) != NULL)
          {
             cData = strFromStrings (cData, chaine);
             if (cData == NULL)
             {
                puts ("memory error");
                break;
             }
          }
          fclose (fichier);
       }
       else
       {
          return NULL;
       }
     
       return cData;
    }
     
    #if 0
    static unsigned int writeToFile (const char *path, const char *data)
    {
       FILE *fichier = fopen (path, "w");
     
       if (fichier != NULL)
       {
          unsigned int lgt = strlen (data);
          unsigned int i = 0;
          for (i = 0; i < lgt; i++)
          {
             fputc (data[i], fichier);
          }
          fclose (fichier);
          return 1;
       }
       else
       {
          return 0;
       }
    }
    #endif
     
    int main (void)
    {
       char *s = readFromFile ("main.c");
       if (s != NULL)
       {
          printf ("%s", s);
          fflush (stdout);
          free (s), s = NULL;
       }
       return 0;
    }
    Il fallait utiliser realloc()... On doit pouvoir faire plus efficace, mais ce code est correct et fonctionnel. Il libère la mémoire correctement.

  3. #3
    Membre extrêmement actif

    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Juin 2003
    Messages
    4 506
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2003
    Messages : 4 506
    Par défaut
    [HS]
    Emmanuel tu as un programme qui se charge de corriger,d'indenter, "de mettre en forme" les codes source parce qu'a chaque fois la rapidité avec laquelle tu le fais cela m'epoustoufle.
    [/HS]

  4. #4
    Expert éminent
    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
    Par défaut
    Citation Envoyé par hegros
    [HS]
    Emmanuel tu as un programme qui se charge de corriger,d'indenter, "de mettre en forme" les codes source parce qu'a chaque fois la rapidité avec laquelle tu le fais cela m'epoustoufle.
    [/HS]
    Ben, c'est intégré dans Code::Blocks (Plugins/Astyle), sinon, j'utilise plutôt GNUIndent 1.91 :

    http://emmanuel-delahaye.developpez....tm#indentation

  5. #5
    Membre émérite Avatar de Ceylo
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2007
    Messages
    1 216
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 216
    Par défaut
    Tout d'abord, merci beaucoup Emmanuel, et après… ben la suite

    Hum. Est-tu bien conscient qu'une chaine est terminée par un 0 ? Parce que quand je vois ça :
    Code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
         unsigned int len1, len2;
         len1 = strlen(str1);
         len2 = strlen(str2);
         char *strCat = malloc(sizeof(char) * (len1 + len2));
    j'ai peur...
    Oui j'en suis conscient, mais vu que je n'ai eu aucun problème de mémoire à cause de ça, je n'ai pas pris la peine de le corriger.

    De plus, j'avais déjà vu des assemblages utilisant realloc(), mais j'obtiens à chaque fois (et encore cette fois-ci avec ton code) une erreur :

    *** malloc[1973]: error for object 0x4378: Pointer being reallocated was not allocated
    Ce qui signifie, si j'ai bien compris, que ma chaine de caractère que je lui ai passé n'avait pas été allouée. Je suis en train de voir comment régler ça…

    À par ça, mon compilateur (GCC) n'a pas aimé les static que tu as ajouté, et j'ai dû les enlever pour qu'il arrête de râler. J'avais les messages suivants :

    Compiling Utilities.c
    Utilities.c:42: warning: `readFromFile' defined but not used
    Utilities.c:72: warning: `writeToFile' defined but not used

    Compiling main.c
    Utilities.h:10: warning: `strFromStrings' used but never defined
    Utilities.h:12: warning: `readFromFile' declared `static' but never defined
    Utilities.h:13: warning: `writeToFile' declared `static' but never defined

    Compiling CIntendation.h
    Utilities.h:10: warning: `strFromStrings' used but never defined
    Utilities.h:12: warning: `readFromFile' declared `static' but never defined
    Utilities.h:13: warning: `writeToFile' declared `static' but never defined


    ld: warning prebinding disabled because of undefined symbols
    ld: Undefined symbols:
    _readFromFile
    _strFromStrings
    _writeToFile
    En espérant que cela peut t'aider

    P.S.: je n'ai pas encore eu le temps d'essayer de tout corriger (afin d'arranger les problèmes), je posterai un nouveau message pour te tenir au courant.

  6. #6
    Expert éminent
    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
    Par défaut
    Citation Envoyé par Spootnik-Dev
    Oui j'en suis conscient, mais vu que je n'ai eu aucun problème de mémoire à cause de ça, je n'ai pas pris la peine de le corriger.
    C'est une erreur grave. (Comportement indéfini).

    http://emmanuel-delahaye.developpez.com/notes.htm#ub

    De plus, j'avais déjà vu des assemblages utilisant realloc(), mais j'obtiens à chaque fois (et encore cette fois-ci avec ton code) une erreur :
    C'est pas normal. Mon code est conforme. Le premier realloc() se fait à partir d'un pointeur NULL, ce qui est tout à fait légal (même comportement que malloc().
    Ce qui signifie, si j'ai bien compris, que ma chaine de caractère que je lui ai passé n'avait pas été allouée. Je suis en train de voir comment régler ça…
    Moi, j'ai mis NULL. Si tu as mis autre chose, je ne répond de rien. encore une fois, mon code est conforme.
    À par ça, mon compilateur (GCC) n'a pas aimé les static que tu as ajouté, et j'ai dû les enlever pour qu'il arrête de râler. J'avais les messages suivants :
    Encore une fois mon code est correct. Si tu fais de la compilation séparée, il ne faut évidement pas que les fonctions exportées soient 'static'.

    http://emmanuel-delahaye.developpez....tes.htm#static

    Comme tu as posté du code partiel, il a bien fallu que je bouche les trous...

  7. #7
    Membre émérite Avatar de Ceylo
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2007
    Messages
    1 216
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 216
    Par défaut
    En ce qui concerne realloc(), je n'ai pas touché à l'intérieur de tes fonctions, j'ai juste enlevé les static.

    Voici le schéma de mon programme :

    A -> B signifie A inclut B

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    main.c -> Utilities.h
           -> CIntendation.h
     
     
    Utilities.c -> Utilities.h
     
     
    CIntendation.c -> CIntendation.h
                   -> Utilities.h
    Donc en gros, mes 3 fonctions qui posent problème (readFromFile(), strFromStrings(), writeToFile()) sont déclarées dans le fichier d'en-tête Utilities.h. Et tous les fichiers d'implementation font appel à lui.

    Au fait, je précise bien que j'utilise le C et non pas le C++…

    Moi, j'ai mis NULL. Si tu as mis autre chose, je ne répond de rien. encore une fois, mon code est conforme.
    Je n'y ai pas touché.

    D'après le lien que tu m'as indiqué je ne dois pas utiliser static, mais il reste toujours le problème du realloc(), et c'est ce qui m'a empêché jusqu'à maintenant d'utiliser un code plus "propre" (mis à par les fautes plus graves de ma part).

  8. #8
    Expert éminent
    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
    Par défaut
    Citation Envoyé par Spootnik-Dev
    En ce qui concerne realloc(), je n'ai pas touché à l'intérieur de tes fonctions, j'ai juste enlevé les static.
    OK. Mais je parle de l'initialisation du pointeur dans readFromFile().

    Tu mettais évidemment, ça foire, on ne peut pas réallouer "". Par contre, je mets et là, ça marche, c'est certain.

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

Discussions similaires

  1. lecture / écriture dans des fichiers text
    Par nadir CoCo dans le forum C++
    Réponses: 6
    Dernier message: 28/06/2012, 09h10
  2. lecture/écriture dans un fichier
    Par benkunz dans le forum Langage
    Réponses: 3
    Dernier message: 10/04/2007, 11h35
  3. probleme lecture ecriture dans des fichiers
    Par xman_genius dans le forum C
    Réponses: 9
    Dernier message: 16/01/2007, 19h50
  4. lecture écriture dans un fichier
    Par poukill dans le forum C++
    Réponses: 9
    Dernier message: 23/05/2006, 11h02
  5. [PERL] Problème lecture/écriture dans un fichier
    Par LE NEINDRE dans le forum Langage
    Réponses: 4
    Dernier message: 17/08/2005, 13h15

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