Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1811 connectés 

 


 Mot :   Pseudo :  
 
 Page :   1  2
Page Suivante
Auteur Sujet :

a propos de char **

n°1234971
Emmanuel D​elahaye
C is a sharp tool
Posté le 31-10-2005 à 13:45:54  profilanswer
 

Reprise du message précédent :

super-tupapau a écrit :

j'ai compris!
 
quand je même ceci:

Code :
  1. typedef struct arch * diskc_arch;
  2. diskc_arch **list = NULL;


 
ca donne un pointeur sur un pointeur sur un pointeur.
j'ai donc supprimer mit

Code :
  1. typedef struct arch diskc_arch;


comme ca j'ai plus d'erreur de compilation ms un segment fault avec list[i]->name = strdup( entry->d_name );


Ben oui. Tu as alloué le tableau mais pas les éléments...

Citation :


et pour le free je ferais comme ca?

Code :
  1. if (file != NULL)
  2.     for( i = 0; i<nb_file-1; i++ )
  3. free(file->next+i);
  4.     free(file);




Insuffisant. Chaque strdup() doit être compensé par un free(). C'est dans la doc, tu ne l'as donc pas lue malgré mon insistance ? Mais qu'est-ce qu'il faut faire pour se faire entendre ?


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
mood
Publicité
Posté le 31-10-2005 à 13:45:54  profilanswer
 

n°1235006
super-tupa​pau
Posté le 31-10-2005 à 14:26:41  profilanswer
 

j'ai lu la doc et je sais qui faut mettre ces free(); reste encore a réussir a les mettre  :heink: .
 

Code :
  1. if (file != NULL){
  2.     for( i = 0; i<nb_file-2; i++ )
  3. free((file->next+i)->name);
  4. free((file->next+i)->chemin);
  5. free(file->next+i);
  6.     free(file->name);
  7.     free(file->chemin);
  8.     free(file);
  9.     }


 

n°1235015
super-tupa​pau
Posté le 31-10-2005 à 14:30:18  profilanswer
 

Pour les éléments du tableau list j'ai fait comme ceci:

Code :
  1. list[i] = malloc( sizeof(diskc_arch) );

n°1235025
super-tupa​pau
Posté le 31-10-2005 à 14:34:22  profilanswer
 

ca donne ceci:

Code :
  1. /* DISKCLEAN --[ Trieur/Nettoyeur de dossier personnel ]-- */
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <dirent.h>
  5. #include <string.h>
  6. /* DISKCLEAN  
  7.    STRUCTURE --[ diskc_arch ]--
  8.    Structure chainée
  9. */
  10. struct arch {
  11. char *name;
  12. char *chemin;
  13. struct arch *next;
  14. struct arch *subdir;
  15. };
  16. typedef struct arch diskc_arch;
  17. /* DISKCLEAN  
  18.    FONCTION --[ diskc_readir ]--
  19.    Lecteur de dossier récursif.
  20.    Retourne un pointeur sur  
  21.    tableau des fichiers présent  
  22.    dans le dossier spécifié
  23.    en argument.
  24. */
  25. /* Nombre de fichier analysé */
  26. int nb_file = 1;
  27. diskc_arch * diskc_readir(const char *directory)
  28. {
  29.     DIR *dir = NULL;
  30.     struct dirent *entry = NULL;
  31.     diskc_arch **list = NULL;
  32.     int i=0;
  33. /* Ouverture du répertoire */
  34.     dir = opendir(directory);
  35.     if (dir == NULL)
  36. return NULL;
  37. /* Lecture du dossier */
  38.     while ((entry = readdir(dir)) != NULL) {
  39. if (strcmp(entry->d_name, "." ) != 0
  40.     && strcmp(entry->d_name, ".." ) != 0) {
  41.     list = realloc( list, nb_file * sizeof *list );
  42.    
  43.    if( list == NULL )
  44.  printf("list est null\n" );
  45.  return NULL;
  46.     /* Compléter les informations du fichiers: nom, chemin, pointeur suivant, pointeur précédent */
  47.     list[i] = malloc( sizeof(diskc_arch) );
  48.     list[i]->name = strdup( entry->d_name );
  49.             list[i]->chemin = strdup( directory );
  50.             list[i]->next = list[i+1];
  51.     list[i]->subdir = NULL;
  52.             nb_file++;
  53. i++;
  54. }
  55.     }
  56.     closedir(dir);
  57.     return list[0];
  58. }
  59. /* DISKCLEAN  
  60.    FONCTION --[ main ]--
  61.    Appeler par le systeme
  62.    Aucun arguments
  63. */
  64. int main( int argc, char ** argv )
  65. {
  66.     int i;
  67.     diskc_arch *file = NULL;
  68.     if(argv[1] == NULL)
  69. return EXIT_FAILURE;
  70.     file = diskc_readir(argv[1]);
  71.     if (file == NULL)
  72. printf("file est null\n" );
  73. return EXIT_FAILURE;
  74.     printf("file+0: %s\n", file->name);
  75.     if (file != NULL){
  76.     for( i = 0; i<nb_file-2; i++ )
  77. free((file->next+i)->name);
  78. free((file->next+i)->chemin);
  79. free(file->next+i);
  80.     free(file->name);
  81.     free(file->chemin);
  82.     free(file);
  83.     }
  84.     return EXIT_SUCCESS;
  85. }


 
et j'obtient à l'execution:
file est null.

n°1235054
super-tupa​pau
Posté le 31-10-2005 à 15:15:20  profilanswer
 

Mes free donner n'importe koi. j'ai un probléme avec le next de la structure arch. je voudrais stocker dedans l'adresse de l'élément suivant en le decalant de un ms je crois que c impossible en fait car le realloc a surment changer complément espace mémoire utiliser entre deux appel.

n°1235065
super-tupa​pau
Posté le 31-10-2005 à 15:21:25  profilanswer
 

voila la correction:
 

Code :
  1. /* DISKCLEAN --[ Trieur/Nettoyeur de dossier personnel ]-- */
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <dirent.h>
  5. #include <string.h>
  6. /* DISKCLEAN  
  7.    STRUCTURE --[ diskc_arch ]--
  8.    Structure chainée
  9. */
  10. struct arch {
  11.     char *name;
  12.     char *chemin;
  13.     struct arch *subdir;
  14. };
  15. typedef struct arch diskc_arch;
  16. /* DISKCLEAN  
  17.    FONCTION --[ diskc_readir ]--
  18.    Lecteur de dossier récursif.
  19.    Retourne un pointeur sur  
  20.    tableau des fichiers présent  
  21.    dans le dossier spécifié
  22.    en argument.
  23. */
  24. /* Nombre de fichier analysé */
  25. int nb_file = 1;
  26. diskc_arch **diskc_readir(const char *directory)
  27. {
  28.     DIR *dir = NULL;
  29.     struct dirent *entry = NULL;
  30.     diskc_arch **list = NULL;
  31.     int i = 0;
  32. /* Ouverture du répertoire */
  33.     dir = opendir(directory);
  34.     if (dir == NULL)
  35. return NULL;
  36. /* Lecture du dossier */
  37.     while ((entry = readdir(dir)) != NULL) {
  38. if (strcmp(entry->d_name, "." ) != 0
  39.     && strcmp(entry->d_name, ".." ) != 0) {
  40.     list = realloc(list, nb_file * sizeof *list);
  41.     if (list == NULL)
  42.  return NULL;
  43.     /* Compléter les informations du fichiers: nom, chemin, pointeur suivant, pointeur précédent */
  44.     list[i] = malloc(sizeof(diskc_arch));
  45.     list[i]->name = strdup(entry->d_name);
  46.     list[i]->chemin = strdup(directory);
  47.     list[i]->subdir = NULL;
  48.     nb_file++;
  49.     i++;
  50. }
  51.     }
  52.     closedir(dir);
  53.     return list;
  54. }
  55. /* DISKCLEAN  
  56.    FONCTION --[ main ]--
  57.    Appeler par le systeme
  58.    Aucun arguments
  59. */
  60. int main(int argc, char **argv)
  61. {
  62.     int i;
  63.     diskc_arch **file = NULL;
  64.     if (argv[1] == NULL)
  65. return EXIT_FAILURE;
  66.     file = diskc_readir(argv[1]);
  67.     if (file == NULL)
  68. return EXIT_FAILURE;
  69.     for (i = 0; i < nb_file - 1; i++) {
  70. printf("%s%s\n", file[i]->chemin, file[i]->name);
  71.     }
  72.     free(file);
  73.     for (i = 0; i < nb_file - 1; i++) {
  74. free(file[i]->name);
  75. free(file[i]->chemin);
  76.     }
  77.     return EXIT_SUCCESS;
  78. }

n°1235070
Emmanuel D​elahaye
C is a sharp tool
Posté le 31-10-2005 à 15:27:50  profilanswer
 

super-tupapau a écrit :

ca donne ceci:
<...>
et j'obtiens à l'execution:
file est null.


 
Ca me parait bien tordu. Dans un premier temps, s'assurer qu'on sait lire un répertoire et stocker les informations qui vont bien :  


/* DISKCLEAN --[ Trieur/Nettoyeur de dossier personnel ]-- */
 
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <string.h>
 
/* DISKCLEAN
   STRUCTURE --[ diskc_arch ]--
*/
 
struct arch
{
    char *name;
    char *chemin;
};
 
typedef struct arch diskc_arch;
 
/* DISKCLEAN
   FONCTION --[ diskc_readir ]--
   Lecteur de dossier récursif.
   Retourne un pointeur sur  
   tableau des fichiers présent  
   dans le dossier spécifié
   en argument.
*/
 
/* -ed-
diskc_arch * diskc_readir(const char *directory)
 
maintenant, il manque une '*'...  
*/
diskc_arch ** diskc_readir(const char *directory, int *p_nb_file)
{
    /* tableau des entrees  */
    diskc_arch **list = NULL;
     
    /* Nombre de fichiers analyses */
    int nb_file = 0;
     
    /* Ouverture du répertoire */
    DIR *dir = opendir(directory);
     
    if (dir != NULL)
    {
        struct dirent *entry = NULL;
        int i=0;
         
        /* Lecture du dossier */
        while ((entry = readdir(dir)) != NULL)
        {
            if (strcmp(entry->d_name, "." ) != 0
                    && strcmp(entry->d_name, ".." ) != 0)
            {
                nb_file++;
                 
                {
                    /* -ed- realloc() a quelques precautions d'usage... */
                    void *tmp = realloc( list, nb_file * sizeof *list );
                     
                    if( tmp != NULL )
                    {
                        list = tmp;
                         
                        /* creer un element */
                        list[i] = malloc (sizeof *list[i]);
                         
                        if (list[i] != NULL)
                        {
                            /* Compléter les informations du fichiers: nom, chemin, pointeur suivant, pointeur précédent */
                            list[i]->name = strdup (entry->d_name );
                            list[i]->chemin = strdup( directory );
                             
                            i++;
                        }
                        else
                        {
                            printf ("memory error (list[%d])\n", i);
                            break;
                        }
                    }
                    else
                    {
                        printf ("memory error (list)\n" );
                        break;
                    }
                }
            }
        }
         
        closedir(dir);
    }
     
    if (p_nb_file != NULL)
    {
        *p_nb_file=nb_file;
    }
    /* -ed-
        return list[0];
     
    mise au point  
    */
    return list;
}
 
 
/* DISKCLEAN
   FONCTION --[ main ]--
   Appeler par le systeme
   Aucun arguments
*/
int main( int argc, char ** argv )
{
    int ret;
     
    /* -ed-
    diskc_arch *file = NULL;
     
    mise au point  
    */
    diskc_arch **file = NULL;
     
    if(argc > 1)
    {
     
        /* Nombre de fichier analysé */
        int nb_file;
         
        file = diskc_readir(argv[1], &nb_file);
        if (file == NULL)
        {
            printf("file est null\n" );
            return EXIT_FAILURE;
        }
        else
        {
            /* -ed-
            Quelle salade. Il faut defaire les choses dans l'ordre inverse...  
             
                    for( i = 0; i<nb_file-2; i++ )
                        free((file->next+i)->name);
                    free((file->next+i)->chemin);
                    free(file->next+i);
                     
                    free(file->name);
                    free(file->chemin);
                    free(file);
            */
            int i;
            for( i = 0; i<nb_file; i++ )
            {
                printf("file[%d]: %s\n", i, file[i]->name);
                 
                free(file[i]->name);
                free(file[i]->chemin);
                free(file[i]);
                 
                /* -ed-
                   mais si il faut parcourir l'arbre, c'est sans doute  
                   insuffisant. Il faut alors utiliser la recursion, c'est le  
                   plus simple a coder, mais pas le plus simple a aprehender.
                */
            }
        }
         
        ret = EXIT_SUCCESS;
    }
    else
    {
        ret = EXIT_FAILURE;
    }
    return ret;
}


Message édité par Emmanuel Delahaye le 31-10-2005 à 15:29:34

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
n°1236015
super-tupa​pau
Posté le 01-11-2005 à 23:08:23  profilanswer
 

Voila j'ai ajouter tous les tests sur les pointeurs et les mallocs (dite le moi si j'en ai oublié) et j'ai aussi mit en place la récursivité:
 

Code :
  1. /* DISKCLEAN --[ Trieur/Nettoyeur de dossier personnel ]-- */
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <dirent.h>
  5. #include <string.h>
  6. #include <sys/types.h>
  7. #include <sys/stat.h>
  8. #include <unistd.h>
  9. /* DISKCLEAN  
  10.    STRUCTURE --[ diskc_arch ]--
  11.    Structure chainée
  12. */
  13. struct arch
  14. {
  15.   char *name;
  16.   char *chemin;
  17.   char *type;
  18.   int level;
  19. };
  20. typedef struct arch diskc_arch;
  21. /* DISKCLEAN  
  22.    FONCTION --[ diskc_readir ]--
  23.    Lecteur de dossier récursif.
  24.    Retourne un pointeur sur  
  25.    tableau des fichiers présent  
  26.    dans le dossier spécifié
  27.    en argument.
  28. */
  29. diskc_arch **
  30. diskc_readir (const char *directory, int *nb_file, diskc_arch ** last_list,
  31.    int level, int *pos)
  32. {
  33. /* Tableau des fichiers analysées */
  34.   diskc_arch **list = NULL;
  35. /* Nombre de fichier analysée */
  36.   int nb = 0;
  37. /* Niveau d'analyse */
  38.   int this_level = level;
  39.   if (last_list != NULL)
  40.     {
  41.       list = last_list;
  42.     }
  43. /* Structure stat */
  44.   struct stat info;
  45. /* Ouverture du répertoire */
  46.   DIR *dir = opendir (directory);
  47.   if (dir != NULL)
  48.     {
  49.       struct dirent *entry = NULL;
  50.       int i = *nb_file;
  51. /* Lecture du dossier */
  52.       while ((entry = readdir (dir)) != NULL)
  53. {
  54.   if (strcmp (entry->d_name, "." ) != 0
  55.       && strcmp (entry->d_name, ".." ) != 0)
  56.     {
  57.       nb++;
  58.       void *tmp = realloc (list, (nb + *nb_file) * sizeof *list);
  59.       if (tmp != NULL)
  60.  {
  61.    list = tmp;
  62.    list[i] = malloc (sizeof (diskc_arch));
  63.    if (list[i] != NULL)
  64.      {
  65.        /* Compléter les informations du fichiers: nom, chemin, pointeur suivant, pointeur précédent */
  66.        list[i]->name = strdup (entry->d_name);
  67.        list[i]->chemin = strdup (directory);
  68.        /* Chemin du fichier */
  69.        char *chemin = NULL;
  70.        chemin = strdup (directory);
  71.        chemin =
  72.   realloc (chemin,
  73.     strlen (chemin) + 1 +
  74.     sizeof (entry->d_name));
  75.        if (chemin != NULL)
  76.   {
  77.     strcat (chemin, entry->d_name);
  78.     if ((stat (chemin, &info)) >= 0)
  79.       {
  80.         if (S_ISDIR (info.st_mode))
  81.    {
  82.      list[i]->type = "Dossier";
  83.    }
  84.         else
  85.    {
  86.      list[i]->type = "Fichier";
  87.    }
  88.         list[i]->level = this_level;
  89.       }
  90.     else
  91.       {
  92.         printf
  93.    ("impossible de récupérer les information de %s\n",
  94.     chemin);
  95.         return NULL;
  96.       }
  97.     free (chemin);
  98.   }
  99.        else
  100.   {
  101.     printf ("impossible d'allouer (chemin)\n" );
  102.     return NULL;
  103.   }
  104.        i++;
  105.      }
  106.    else
  107.      {
  108.        printf ("impossible d'allouer (list[%i])\n", i);
  109.        return NULL;
  110.      }
  111.  }
  112.       else
  113.  {
  114.    printf ("impossible d'allouer (list)\n" );
  115.    return NULL;
  116.  }
  117.     }
  118. }
  119.       closedir (dir);
  120.       if (nb_file != NULL)
  121. {
  122.   *nb_file = *nb_file + nb;
  123. }
  124. /* Récursivité */
  125.       if( pos != NULL ){
  126.       int j = *pos;
  127.       while (j < *nb_file)
  128. {
  129.   if (list[j]->type == "Dossier" && list[j]->level == this_level)
  130.     {
  131. /* Chemin du fichier */
  132.       char *chemin = NULL;
  133.       chemin = strdup (directory);
  134.       chemin = realloc (chemin, sizeof (*chemin) + NAME_MAX+1 + 1); /* on ajoute 1 pour le / */
  135.       if (chemin != NULL)
  136.  {
  137.    strcat (chemin, list[j]->name);
  138.    strcat (chemin, "/" );
  139.    list =  diskc_readir (chemin, nb_file, list, this_level+1, pos);
  140.    free (chemin);
  141.  }
  142.       else
  143.  {
  144.    printf ("impossible d'allouer (chemin)" );
  145.    return NULL;
  146.  }
  147.     }
  148.   j++;
  149. }
  150.    
  151.     *pos = j;
  152.     }
  153.     else{
  154.  printf("impossible de récupérer la position dans le dossier" );
  155. return NULL;
  156.     }
  157.     }
  158.   else
  159.     {
  160.       printf ("impossible d'ouvrir le répertoire: %s\nVérifiez si vous avez les droits d'accès sur ce dossier.\n", directory);
  161.     }
  162.   return list;
  163. }
  164. /* DISKCLEAN  
  165.    FONCTION --[ main ]--
  166.    Appeler par le systeme
  167.    Aucun arguments
  168. */
  169. int
  170. main (int argc, char **argv)
  171. {
  172.   int i;
  173.   diskc_arch **file = NULL;
  174.   /* Nombre de fichier analysé */
  175.   int nb_file = 0;
  176.   int pos = 0;
  177.   if (argv[1] != NULL)
  178.     {
  179.       file = diskc_readir (argv[1], &nb_file, NULL, 0, &pos);
  180.       if (file != NULL)
  181. {
  182.   for (i = 0; i < nb_file; i++)
  183.     {
  184.       printf ("[%s N°%i][LEVEL]:%i:%s%s\n", file[i]->type, i, file[i]->level, file[i]->chemin,
  185.        file[i]->name);
  186.     }
  187.   for (i = 0; i < nb_file; i++)
  188.     {
  189.       free (file[i]->name);
  190.       free (file[i]->chemin);
  191.       free (file[i]);
  192.     }
  193. }
  194.       else
  195. {
  196.   return EXIT_FAILURE;
  197. }
  198.     }
  199.   else
  200.     {
  201.       return EXIT_FAILURE;
  202.     }
  203.   return EXIT_SUCCESS;
  204. }


 
note: le programme est tres lent sur de tres gros dossier ( logic ) or il serait preferable qu'il soit plus rapide vu qu'il a pour objectif de rechercher les fichiers en double. enfin il a planter sur mon dossier home apres une 20 de seconde:
 
la glib me signalant un double free. il y a un test faux ds mon programme?


Message édité par super-tupapau le 01-11-2005 à 23:16:31
n°1236031
super-tupa​pau
Posté le 01-11-2005 à 23:20:58  profilanswer
 

j'ai resolu le problème lenteur en ignorant les dossier commencant par un '.' car ces dossiers ne sont pas directement modifier pas l'utilisateur il ont donc pas besoin d'être vérifiés.

mood
Publicité
Posté le   profilanswer
 

 Page :   1  2
Page Suivante

Aller à :
Ajouter une réponse
 

Sujets relatifs
à propos de cadres.. ou recherche d'une autre solutionaide à propos strstr
Fonction qui modifie un char *a propos des combobox
[HTML] question toute bete à propos des tableaux Question a propos de Visual C++ 2005
[batch] longueur d'une chaine de charConvertir un char en int ?!
PB: Fonction de conversion Unicode->charerror: invalid operands of types 'const char [15]' and 'short ..
Plus de sujets relatifs à : a propos de char **


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR