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 :

Récupérer le contenu d'un fichier puis le mettre dans une chaîne


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2021
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2021
    Messages : 2
    Par défaut Récupérer le contenu d'un fichier puis le mettre dans une chaîne
    Bonsoir !

    Voici mon problème: on se donne un fichier que je vous écris ci dessous :

    1
    7
    1 3 5 8 6 7 4 3 2 1 9 6 4 3 6 2
    +*++**-///*-/-+-*-*++++-
    2
    20
    J'aimerais transformer ce fichier texte en une unique chaîne de caractère et pour cela j'ai écris cette fonction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    void all_in_one(int max_line, char *buffer,FILE* f){
        char *chaine=malloc(sizeof(char)*max_line);
        for(int i=0,n=0;i<6;i++){
            fgets(chaine,max_line,f);
            sprintf(buffer+n,"%s\0",chaine);
            n=n+strlen(chaine);
        }
        fseek(f, 0, SEEK_SET);
        free(chaine);
        return;
    }
    Sauf que lorsque je lance valgrind, j'obtiens ==103== Invalid write of size 1, j'avais essayé avec la fonction strcat mais j'ai une erreur du même registre...

    Quand j'essaye de cibler mon problème en ne récupérant qu'une ligne particulière j'ai exactement le même soucis Invalid write of size 1 :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void give_me_operator(FILE* f,int max_line,char *p){
        char chaine[max_line];
        for(int i=0;i<4;i++){
            fgets(chaine, max_line, f);
        }
        fseek(f, 0, SEEK_SET);
        strcpy(p, chaine);
        return;
    }
    Je m'en remets à vous, merci d'avoir pris le temps de me lire !

  2. #2
    Membre émérite
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Juillet 2020
    Messages
    352
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Juillet 2020
    Messages : 352
    Par défaut
    Bonjour,
    plusieurs points :

    • valgrind t'indique quel ligne fait le débordement … ça devrait fortement aider le debug (il faut impérativement compiler en mode debug soit avec l'option `-g` avec gcc et clang);
    • relis la doc de fgets … surtout la partie concernant le paramètre size et ce qui se passe avec le caractère '\0' :
      fgets() reads in at most one less than size characters from stream and stores them into the buffer pointed to by s.
      Reading stops after an EOF or a newline. If a newline is read, it is stored into the buffer. A terminating null byte
      ('\0') is stored after the last character in the buffer.
    • attention à l'utilisation des VLA qui peuvent rapidement exploser la pile;
    • je ne peux que te conseiller d'implémenter un string buffer qui croît dynamiquement (avec un facteur de croissance entre 1.5 et 2) avec toutes les fonctions qui vont bien. Cela simplifiera non seulement ton code mais également le debug.


    Sinon si tu es sous *nix, tu as mmap qui permet d'accéder au contenu d'un fichier directement en mémoire …

  3. #3
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 832
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 832
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par Vantin19 Voir le message
    J'aimerais transformer ce fichier texte en une unique chaîne de caractère et pour cela j'ai écris cette fonction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    void all_in_one(int max_line, char *buffer,FILE* f){
        char *chaine=malloc(sizeof(char)*max_line);
        for(int i=0,n=0;i<6;i++){
            fgets(chaine,max_line,f);
            sprintf(buffer+n,"%s\0",chaine);
            n=n+strlen(chaine);
        }
        fseek(f, 0, SEEK_SET);
        free(chaine);
        return;
    }
    Déjà pas besoin de mettre le "\0' dans sprintf(). Toute fonction de création de chaine s'occupe elle-même de mettre le '\0' qui va bien. Accessoirement tu peux remettre strcat(), le souci ne vient pas de là. En fait d'ailleurs il n'y a pas de réel souci avec cette fonction. Pour peu que "buffer" ait une taille suffisante quand on le lui passe et que le fichier ait été bien ouvert avec possibilité de lecture elle "fonctionne" parfaitement. Je ne dis pas qu'elle est parfaite, comme par exemple cette boucle de 0 à 6 limitant un peu sa "généricité" (elle ne marchera que pour les fichiers de 6 lignes, pas ceux de 5 ni ceux de 7) mais son code est sans erreur, y compris avec ce "return" inutile.

    PS: dans un but de correspondre à la réalité, je travaillerais avec max_line + 1 dans la fonction, afin que "max_line" représente le nb de caractères "réels" de la ligne et non pas le nombre de caractères "alloués" (auquel cas on en perd un pour laisser la place au '\0').
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  4. #4
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2021
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2021
    Messages : 2
    Par défaut
    Bonsoir, je vous remercie d'avoir pris le temps de me répondre, en effet le problème c'est que je générais un tableau de taille insuffisante à cause du \0 ça m'apprendra à utiliser des fonctions sans savoir réellement ce qu'elle font, encore merci !!

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

Discussions similaires

  1. ouvrir un fichier puis le copier dans une base vba
    Par emy31 dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 05/08/2016, 13h31
  2. Réponses: 6
    Dernier message: 25/11/2014, 10h22
  3. Réponses: 1
    Dernier message: 22/04/2010, 00h32
  4. Réponses: 8
    Dernier message: 08/03/2007, 16h54
  5. Réponses: 3
    Dernier message: 09/09/2006, 13h24

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