Rechercher : dans
Par :

Langage c : récupérer un dir

Dernière réponse le 29 jui 2005 à 12:50:28 mackoncef, le 28 jui 2005 à 10:19:18 
 Signaler ce message aux modérateurs

J'ai posté cette question sur le forum Programmation mais j'ai pas eu de réponse. J'espère que j'aurai des réponse ici.


bonjour tout le monde,
Je suis entrain de développer une petite application en langage C. Et pour ceci j'ai besoin d'une fonction qui permette de récupérer la structure arborescente d'un répértoire, c.a.d une fonction du style :
arbre récupérerArbre(int fd);
où fd représente un descripteur de fichier pointant sur un répértoire.
normalement une telle fonction devrait exister dans les includes, en fouillant un peu j'ai trouvé un certain dirent.h qui propose une structure dirent (je ne sait pas c'est quoi exactement) et des fonctions du genre scandir, readdir, getdirentries ... mais j'arrive pas a les exploiter.
Sinon la méthode que j'ai essayé c'est de faire dans mon programme un system("ls -R nomDuRepertoire > tmp"), ouvrir le fichier tmp qui contient des lignes du genre :

rep1/ :
rep2
file1
file 2

rep1/rep2/:
file3
file4
....

et de constituer mon arbre en traitant ligne par ligne le contenu de ce fichier, mais cette solution est moyennement satisfaisante car elle est un peu longue vu la taille en profondeur des répértoires que je souhaite analyser, et en plus le résultat est conditionné par la version du 'ls' installé sur unix. Une autre version donnera peut etre un fichier tmp dont la syntaxe peut changer, ce qui fait que mon application risque de ne pas fonctionner sur d'autres machines...
bref si quelqu'un sait si une telle fonction existe ou sait comment faire pour la programmer d'une manière plus efficace...

Meilleures réponses pour « langage c : récupérer un dir » dans :
Langage C++ - Les types de données Voir Les types de données Les données manipulées en langage C++, comme en langage C, sont typées, c'est-à-dire que pour chaque donnée que l'on utilise (dans les variables par exemple) il faut préciser le type de donnée, ce qui permet de connaître...
Langage C - Les chaînes de caractères VoirQu'est-ce qu'une chaîne de caractères ? Une chaîne de caractères (appelée string en anglais) est une suite de caractères, c'est-à-dire un ensemble de symboles faisant partie du jeu de caractères, défini par le code ASCII. En langage C, une chaîne...
Langage C - Les types de données VoirLes types de données Les données manipulées en langage C sont typées, c'est-à-dire que pour chaque donnée que l'on utilise (dans les variables par exemple) il faut préciser le type de donnée, ce qui permet de connaître l'occupation mémoire (le...
Langage C - Les variables VoirLe concept de variable Une variable est un objet repéré par son nom, pouvant contenir des données, qui pourront être modifiées lors de l'exécution du programme. Les variables en langage C sont typées, c'est-à-dire que les données contenues dans...

1

jipicy, le 28 jui 2005 à 11:02:48
  • +4

Salut,

Tiens voilà 2 programmes tirés de cet ouvrage [http://www.editions-eyrolles.com/Livre/9782212091298/progra­mmation-linux](les codes sources sont téléchargeables sur la page), qui traitent de ton problème et de l'emploi de "dirent.h" et autres commandes associées :
1- /

/*  We start with the appropriate headers and then a function, printdir,
    which prints out the current directory.
    It will recurse for subdirectories, using the depth parameter is used for indentation.  */

#include <unistd.h>
#include <stdio.h>
#include <dirent.h>
#include <string.h>
#include <sys/stat.h>

void printdir(char *dir, int depth)
{
    DIR *dp;
    struct dirent *entry;
    struct stat statbuf;

    if((dp = opendir(dir)) == NULL) {
        fprintf(stderr,"cannot open directory: %s\n", dir);
        return;
    }
    chdir(dir);
    while((entry = readdir(dp)) != NULL) {
        lstat(entry->d_name,&statbuf);
        if(S_ISDIR(statbuf.st_mode)) {
            /* Found a directory, but ignore . and .. */
            if(strcmp(".",entry->d_name) == 0 ||
                strcmp("..",entry->d_name) == 0)
                continue;
            printf("%*s%s/\n",depth,"",entry->d_name);
            /* Recurse at a new indent level */
            printdir(entry->d_name,depth+4);
        }
        else printf("%*s%s\n",depth,"",entry->d_name);
    }
    chdir("..");
    closedir(dp);
}

/*  Now we move onto the main function.  */

int main()
{
    printf("Directory scan of /home:\n");
    printdir("/home",0);
    printf("done.\n");

    exit(0);
}
2- /
/*  We start with the appropriate headers and then a function, printdir,
    which prints out the current directory.
    It will recurse for subdirectories, using the depth parameter is used for indentation.  */

#include <unistd.h>
#include <stdio.h>
#include <dirent.h>
#include <string.h>
#include <sys/stat.h>

void printdir(char *dir, int depth)
{
    DIR *dp;
    struct dirent *entry;
    struct stat statbuf;

    if((dp = opendir(dir)) == NULL) {
        fprintf(stderr,"cannot open directory: %s\n", dir);
        return;
    }
    chdir(dir);
    while((entry = readdir(dp)) != NULL) {
        lstat(entry->d_name,&statbuf);
        if(S_ISDIR(statbuf.st_mode)) {
            /* Found a directory, but ignore . and .. */
            if(strcmp(".",entry->d_name) == 0 ||
                strcmp("..",entry->d_name) == 0)
                continue;
            printf("%*s%s/\n",depth,"",entry->d_name);
            /* Recurse at a new indent level */
            printdir(entry->d_name,depth+4);
        }
        else printf("%*s%s\n",depth,"",entry->d_name);
    }
    chdir("..");
    closedir(dp);
}

/*  Now we move onto the main function.  */

int main(int argc, char* argv[])
{
    char *topdir, pwd[2]=".";
    if (argc != 2)
        topdir=pwd;
    else
        topdir=argv[1];

    printf("Directory scan of %s\n",topdir);
    printdir(topdir,0);
    printf("done.\n");

    exit(0);
}
Le 1er programme est statique au niveau du répertoire à explorer, le second est dynamique, emploi :
programme  /chemin_rep/a_explorer  | more
M'en demande pas plus (je pompe rien en C), j'avais ça sous la main qui semblait correspondre à ta demande ;-)) Z'@+...che.
JP : Zen, my Nuggets ! ;-)
Le savoir n'est bon que s'il est partagé. 

Répondre à jipicy

2

mackoncef, le 28 jui 2005 à 14:07:26

Merci,
cette fonction printdir correspond a peu près a ce que je cherche avec quelques modificcations

Répondre à mackoncef

3

 kilian, le 29 jui 2005 à 12:50:28
  • +1

Salut,

Si tu veux j'ai fait une fonction il ya deux jours qui affiche chaque fichiers avec son chemin dans une arborescence.
C'est peut être un plus court:

// Determine si le nom d'un rep se refere à un rep valide
int is_dir(char *path)
{
	DIR *is_folder=NULL;

	is_folder=opendir(path);
	if (is_folder!=NULL){
		closedir(is_folder);
		return 1;
	}	
	
	closedir(is_folder);
	return 0;	
		
}

int scan_folder(char *dirname)
{
	DIR *folder;
	struct dirent *entity;
	char *real_path=NULL;
	
        folder=opendir(dirname);
	if (folder==NULL)
		return -1;
	
	while (entity=readdir(folder)){
		if(real_path!=NULL){
			free(real_path);
			real_path=NULL;
		}
		if(!strcmp(entity->d_name,".") || !strcmp(entity->d_name,"..") ) //Evite quelques problemes sous Unix/Linux
			continue;
		real_path=(char *)malloc( strlen(dirname) + strlen(entity->d_name) + 2);/* Si c'est+1 au lieu de +2, j'ai parfois un problème de segmentation. Sais pas pourquoi .. */
		sprintf(real_path,"%s/%s",dirname,entity->d_name);
		if( is_dir(real_path) == 1 ){
			scan_folder(real_path);
		}	
		else
                       printf("Fichier: %s\n",real_path);
			
			
		
	}
	closedir(folder);
	if (real_path!=NULL){
		free(real_path);
		real_path=NULL;
	}
			
	return 0;
}


Ya juste à bidouiller un ptit peu pour afficher comme tu voulais le faire.

Répondre à kilian