begin process at 2012 05 29 05:01:48
  Trouver un code source :
 
dans
 
Accueil > Forum > 

Archive C/C++

 > 

Archives

 > 

Au secours

 > 

fonction récursive => segmention fault


Derniers messages déposésPoser une question dans le forum ou lancer une discussion

fonction récursive => segmention fault

jeudi 16 mars 2006 à 18:47:15 | fonction récursive => segmention fault

mayapour

Bonjour, j'ai absolument besoin de votre aide !!

Lorque j'utilise ma fonction avec pour option -R pour afficher le contenu du dossier, et si celui-ci en contient d’autre, cette option affiche aussi leurs contenu (d'où la récursivité).

1er problème : elle affiche les fichiers ou dossiers en DOUBLE.
2ème prblème : elle retourne "segmention fault". La fontion ne fait pas la récursivité.

Pourquoi ?

Voici le code :

#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <pwd.h>
#include <grp.h>
#include <time.h>
#include <string.h>
#include <unistd.h>

typedef struct options_s{
  int recursive, longdisplay, numeric, all, displaydirnames ;
} options_t ;
options_t _options = { 0, 0, 0, 0, 0 } ;

/* renvoie la dernière composante d'un chemin
   (ce qui suit le dernier slash, s'il y en a un) */
char * afterslash (const char * name) {
  char * path = strrchr (name, '/') ;

  if (path == name) return path ;
  if (!path)        return strchr(name, name[0]) ;
  else              return path + 1 ;
}

/* une fonction qui indique si le nom commence par un point */
int allbutdotfiles (const struct dirent* d) {
  char* realname = afterslash(d->d_name) ;
  return realname[0]!='.' ;
}

/* une fonction qui indique si le nom est . ou .. */
int allbutdotand2dots (const struct dirent* d) {
  char* realname = afterslash(d->d_name) ;

  if (realname[0]!='.')    return 1 ;
  if (realname[1]=='\0')   return 0 ;
  if (realname[1]!='.')    return 1 ;
  if (realname[2]=='\0')   return 0 ;
  return 1 ;
}

/* affichage d'un fichier */
void printfile (char * name, options_t * options) {
  struct stat s;
  char access_chars [] = "rwxrwxrwx";
  int  access_masks [] = { 0400, 0200, 0100, 040, 020, 010, 4, 2, 1 };
  char type_chars   [] = "-dbcl";
  int  type_masks   [] = { S_IFREG, S_IFDIR, S_IFBLK, S_IFCHR, S_IFLNK };
  struct passwd * p;
  struct group  * g;
  int i ;
  char date[12] ;

/* (avec option "-l") */
  if ( ! options->longdisplay )
    puts(afterslash(name));
  else {
    if ( lstat(name,&s) == -1) {
      perror("lstat");
      exit(-1);
    }

    for (i=0; i<strlen(type_chars); i++)
      if (s.st_mode & type_masks[i]) {
    putchar(type_chars[i]);
    break;
      }
   
    if (i==strlen(type_chars))      putchar('?');

    for (i=0; i<strlen(access_chars); i++) {
      if (s.st_mode & access_masks[i]) putchar(access_chars[i]) ;
      else putchar('-') ;
    }

    printf (" %4d ", s.st_nlink) ;

    if (options->numeric)
      printf("%-8d %-8d ",s.st_uid,s.st_gid) ;
    else {
      p = getpwuid (s.st_uid) ;
      g = getgrgid (s.st_gid) ;

      if (p)    printf ("%-8s ",p->pw_name);
      else    printf ("%-8d ",s.st_uid);

      if (g)    printf ("%-8s ",g->gr_name);
      else    printf ("%-8d ",s.st_gid);
    }
    printf ("%8d ", s.st_size) ;

    strftime (date,13,"%b %d %H:%M",gmtime(&s.st_mtime)) ;
    printf ("%12s ",date) ;
  }
  name = afterslash (name) ;
  puts(name) ;
}

/* affichage d'un fichier ou répertoire.
   pour un fichier, on l'affiche simplement.
   pour un répertoire, on fait une descente récursive
   (si l'option -R est spécifiée) */
void printdirectory (char* name, options_t* options){
  struct stat s;
  struct dirent ** files;
  int n, i;
  char * fullname;

  /* d'abord, si "name" ne correspond pas à un répertoire,
     on l'affiche directement */
  if ( stat(name,&s) == -1 ) {
    perror("stat");
    exit(-1);
  }

  if (!S_ISDIR(s.st_mode))
    printfile (name,options) ;
  /* sinon, c'est un répertoire, donc on va le parcourir */
  else {
    /* est-ce qu'on affiche tout (sauf . et ..), ou bien
       est-ce qu'on cache les fichiers commençant par un point ? */
    int(*selectfun)(const struct dirent*) =
      options->all ? allbutdotand2dots : allbutdotfiles ;

    n = scandir (name, &files, selectfun, alphasort) ;

    if (n == -1) {
      perror("scandir");
      exit(-1);
    }

    if (options->displaydirnames || options->recursive)
      printf("%s:\n",afterslash(name));

    for (i=0; i<n; i++) {
      fullname = (char *)malloc(strlen(name)+1+strlen(files[i]->d_name)+1);
      if ( fullname == NULL ) {
    perror("malloc");
    exit(-1);
      }

      sprintf (fullname, "%s/%s", name, files[i]->d_name) ;
      printfile (fullname,options) ;
      free(fullname);
    }
    free(files);

    /* maintenant, on fait l'éventuelle descente récursive */
    if (options->recursive) {
      for (i=0; i<n; i++) {
    fullname = (char *)malloc(strlen(name)+1+strlen(files[i]->d_name)+1);
    if ( fullname == NULL ) {
      perror("malloc");
      exit(-1);
    }

    sprintf (fullname, "%s/%s", name, files[i]->d_name) ;
    if ( stat(fullname,&s) == -1 ) {
      perror("stat");
      exit(-1);
    }

    if (S_ISDIR(s.st_mode)) {
      puts(""); /* pour séparer l'affichage des répertoires */
      printdirectory (fullname, options) ;
    }
    free(fullname);
      }
      free(files);
    }
  }
}


int main (int c, char**v) {
  options_t options = _options ;
  int option ;
  int i;

  while (-1!=(option=getopt(c,v,"Rlna")))
    switch (option) {
    case 'R': options.recursive = 1;    break;
    case 'l': options.longdisplay = 1;    break;
    case 'n': options.numeric = 1;        break;
    case 'a': options.all = 1;          break;
    }
 
  if (c == optind)
    printdirectory(".",&options);
  else {
    if (optind < c-1)
      options.displaydirnames++ ;

    for (i=optind; i<c; i++) {
      printdirectory(v[i],&options) ;

      if (i+1!=c)
    puts(""); /* pour séparer les différents répertoires */
    }
  }
  return 0;
}

jeudi 16 mars 2006 à 19:23:59 | Re : fonction récursive => segmention fault

mayapour

Pardon c'est 'Segmentation fault'


Cette discussion est classée dans : int, name, char, options, st


Répondre à ce message

Sujets en rapport avec ce message

tableaux de chaines en argument de fonction [ par ashboody ] je dispose d'une fonction connect a laquelle je doit passer un tableau de chaine char **RegisteredChannels_Name. Pour cela je déclare mon tableau dans Quel est le bug ? [ par mayapour ] Bonjour, En testant ce petit programme qui est l'équivalent du ls sous linux avec différentes options, je me suis appercu qu'il affiche un . (point) e quelqun peut il corriger ce qui ne vas pas dans ce programme s'il vous plait [ par gasy72 ] en fait je commence à programmer en C++ maintenant et j'apprend en modifiant et en essayant de comprendre certain programme.voici par exemple un code empêcher de taper un char... [ par mmx1 ] bonsoir, pendant le developpement d'un pathfinding pour mes études, je suis bloqué sur un truc certainement tout bête et qui peut ce retrouvé dans bie problem avec un char[] [ par kibab ] Bounour a vous tous, je suis nouveau de ce langage et je m'amuse à faire des épreuves diverses.Ici il y a un petit example mais jái un problem:#includ initialisation d'un tablo char et int [ par ddd666 ] bonjour,je narrive pas à initialiser un tablo char ni un tablo int. kelkun pourré maider svpmerci d'avance Convertir une valeur d'un tableau de char en int [ par impskil ] Bonjour.J'ai un tableau de char: char line[3000];Je veux reccuperer une valeur à l'interrieur du tableau et enssuite la convertir au format int ou dou Petit problème pour créer un arbre binaire [ par dragarth1 ] Bonjour j'ai un travail à faire pour l'école, il faut que je crée un arbre binaire à partir d'un fichier, comme un arbre généalogique, la racine étant problème de déclaration int [ par mayapour ] Bonjour, Dans un programme en C, je souhaite afficher les infos d'un dossier : void printfile (char * name, options_t * options) {   struct stat s; convertir int en char [ par moumouteb ] Bonjour, J'ai trouvé une fonction qui permet de convertir les char en int : atoi(). Existe-t-il la même pour convertir les int en char? merci d'avance


Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Mai 2012
LMMJVSD
 123456
78910111213
14151617181920
21222324252627
28293031   

Consulter la suite du CalendriCode

Photothèque

A découvrir



 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 1,076 sec (4)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales