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 :

Probleme de concatenation


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Octobre 2007
    Messages
    28
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 28
    Par défaut Probleme de concatenation
    Bonjour,
    Alors voila, après avoir chercher de longues heures sur le net, c'est en désespoir de cause que je viens ici, car je ne sais plus trop quoi tenter.

    Donc, je dois réaliser un programme qui va lire, ligne par ligne, tous les fichiers d'un repertoire (nommé test dans mon code). Je récupère donc les noms de fichier, et je les concatene avec le chemin du répertoire. Ensuite, ma méthode readVote(filename) va s'occuper de la lecture.

    Actuellement le programme fonctionne, mais je rencontre des problèmes que je n'arrive pas à résoudre: Si je supprime la ligne "char * newname = "";", qui ne sert à rien du tout(c'était un ancien test), le compitaleur(gcc sous cygwin) me renvoie une segmentation fault. Idem, si je supprime "printf("%d \n",strlen(long_s));", à nouveau, erreur de segmentation.

    J'ai pensé que cela devait venir d'overflow au niveau de mes tableaux de caractères, et j'ai tenté de regler ca avec un malloc, ou en attribuant une taille fixe à mon tableau long_s, mais j'obtenais le même genre de problème qu'expliqué ci-dessus.

    Ensuite, j'ai remarqué un autre problème: Si je créais une variable char test[10] au tout debut de ma main, et que je regardais la taille, j'obtenais 11(normal). Mais si je la créais juste après "char * newname = "";", j'obtenais 5, et si je la créais entre "int size;" et "char * newname = "", j'obtenais une segmentation fault! Bref, je commence à ne plus rien y comprendre...

    Donc voila, si quelqu'un a déjà eu ce genre de problème, ou sait d'où vient le mien, ca m'aiderait fortement, parque la je ne vois plus trop quoi faire:/.



    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
    int main(int argc, char* argv[]){
      int i;
      int x;
      int size;
      char const * dirPath = "./test/";
     
      DIR * rep = opendir("./test");
     
        if (rep != NULL) {
            struct dirent * ent;
            while ((ent = readdir(rep)) != NULL) {
     
               char * name = (*ent).d_name;
               if(strcmp(".",name) && strcmp("..",name)){
     
                  size = strlen(name) + strlen(dirPath) +1;
                  char * long_s = malloc(size*sizeof(char));
     
                  printf("%d \n",strlen(long_s)); //PROBLEME SI ON SUPPRIME CETTE LIGNE
                  i=0;
                  x=0;
     
                  while (dirPath[i]){
                    long_s[i] = dirPath[i];
                    ++i;
                  }
                  while (name[x]){
                    long_s[i] = name[x];
                    ++i;
                    ++x;
                  }
     
                 long_s[i] = '\0';
                 readVote(long_s);
                 free(long_s);
                }
            }
            closedir(rep);
        }
        return 0;
    }

  2. #2
    Membre émérite
    Avatar de Pouet_forever
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    671
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 671
    Par défaut
    Fais très attention avec les déclarations char *. Je te conseille de mettre const parce que la chaîne pointée n'est pas modifiable :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    char const * dirPath = "./test/";
    char const * newname = "";
    En faisant ça, tu ne copies pas la chaîne mais tu fais juste pointer 'name' sur 'ent->d_name'.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char * name = (*ent).d_name;
    Ton problème se situe au niveau du char * long_s ;, il faut bien que tu alloues avec malloc ou alors que tu déclares un tableau statique.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    char * long_s = malloc(size * sizeof *long_s));
    /* Ou */
    char long_s[100] = "";

  3. #3
    Membre confirmé
    Inscrit en
    Octobre 2007
    Messages
    28
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 28
    Par défaut
    Alors premièrement, merci de te pencher sur mon problème.

    Ensuite, j'ai testé les modifications que tu m'a conseillées.
    J'ai édité le code afin de le mettre à jour, mais même avec malloc/free, si je supprime la ligne printf("%d \n",strlen(long_s));, il lit bien le premier fichier, appelé f1.txt, mais lorsqu'il veut lire le 2ème, il ne parvient pas à l'ouvrir. Ma methode de lecture renvoie le nom du fichier lorsqu'il y a une erreur, et le nom est en réalité f2.txt, alors qu'il devrait normalement être ./test/f2.txt, d'où l'impossibilité d'ouvrir le fichier. Donc le problème survient pendant la 2eme itération de boucle, où la chaine dirPath n'est pas pris en compte, mais je vois pas trop pourquoi:/.
    A noter que lorsque je laisse mon printf("%d \n",strlen(long_s));, la première fois qu'il passe dans la boucle, il imprime 0, et la seconde fois, il imprime 13...

    J'ai regardé ta 2ème solution également, qui marche si je laisse le printf("%d \n",strlen(long_s));, mais qui renvoie une segmentation fault si je l'enleve.

    Enfin, ta 2ème remarque, concernant la ligne char * name = (*ent).d_name;, je ne dois rien modifier non?

  4. #4
    Membre confirmé
    Inscrit en
    Octobre 2007
    Messages
    28
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 28
    Par défaut
    @Obsidian: Merci également pour ton aide.
    Effectivement, declarer le pointeur pointant vers nulle part est dangereux, je m'en souviens maintenant. Cependant, même enfaisant un malloc, si je supprime le printf("%d \n",strlen(long_s)); j'ai un problème, comme j'ai expliqué en réponse à pouet_forever.
    Tu me dis que la taille de size, lors que mon malloc, est declarée mais non initialisée, mais la ligne juste au dessus du malloc, size = strlen(name) + strlen(dirPath) +1;, initialise size (à 14 si je l'imprime), donc normalmeent cela ne devrait pas poser problème, non?

  5. #5
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 477
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 477
    Par défaut
    Citation Envoyé par Slash10 Voir le message
    Tu me dis que la taille de size, lors que mon malloc, est declarée mais non initialisée, mais la ligne juste au dessus du malloc, size = strlen(name) + strlen(dirPath) +1;, initialise size (à 14 si je l'imprime), donc normalmeent cela ne devrait pas poser problème, non?
    Effectivement, j'ai fait un copier-coller de ton code dans un éditeur pour y voir plus clair et cette ligne a disparu. Mauvaise manip'

  6. #6
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Par défaut
    Pourrais-tu poster le corps de la fonction readVote() également

  7. #7
    Membre émérite
    Avatar de Pouet_forever
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    671
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 671
    Par défaut
    Citation Envoyé par Slash10 Voir le message
    Enfin, ta 2ème remarque, concernant la ligne char * name = (*ent).d_name;, je ne dois rien modifier non?
    Non, mais c'est pour être sûr que tu sais ce que tu fais.

    J'ai remarqué que ton closedir(rep); était mal placé aussi (une accolade trop loin).

    Comme l'a dit obsidian, tu fais un strlen sur quelque chose qui n'est pas initialisé donc tu as toutes les chances que ton programme plante. Enlève purement et simplement cette ligne (même si ton programme plante), ou alors mets la après 'long_s[i] = '\0';'.

  8. #8
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 477
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 477
    Par défaut
    Citation Envoyé par Slash10 Voir le message
    Mais si je la créais juste après "char * newname = "";", j'obtenais 5, et si je la créais entre "int size;" et "char * newname = "", j'obtenais une segmentation fault! Bref, je commence à ne plus rien y comprendre...
    Et, à mon avis, il n'y a rien à comprendre car il s'agit d'un comportement indéterminé.

    À première vue, quand tu écris :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
                  char * long_s ;//= malloc(size*sizeof(char));
    Tu crées un pointeur qui ne pointe vers nulle part. Hauts risques de plantage. Si tu l'initialises soit avec ton malloc(), soit en déclarant comme un tableau, il pointe vers une zone valable mais vide à priori (comprendre : aux données non initialisées). Ton appel à strlen(long_s) a toutes les chances d'échouer s'il ne rencontre pas un '\0' à temps (et renverra de toutes façons une valeur farfelue).

    D'autre part, lorsque tu fais ton malloc(), tu alloues une zone de taille multiple de size, qui est déclarée mais n'est pas initialisée non plus.

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

Discussions similaires

  1. Probleme pour concatener 2 objets Set
    Par PORTES dans le forum C++
    Réponses: 13
    Dernier message: 16/04/2007, 15h02
  2. Probleme de concatenation dans une requete
    Par toddy_101 dans le forum Requêtes
    Réponses: 4
    Dernier message: 12/01/2007, 14h43
  3. Réponses: 4
    Dernier message: 03/11/2006, 17h11
  4. [FLASH 8] Probleme de concatenation
    Par kubito dans le forum ActionScript 1 & ActionScript 2
    Réponses: 4
    Dernier message: 14/04/2006, 14h31
  5. probleme de concatenation
    Par cyna dans le forum C
    Réponses: 2
    Dernier message: 23/08/2002, 10h41

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