Rechercher : dans
Par :

Ls recursif en C

Dernière réponse le 15 nov 2003 à 12:47:12 bibiloute, le 13 nov 2003 à 11:03:41 
 Signaler ce message aux modérateurs

Slt! voila j'ai un petit probleme (vous vous en seriez doute!) j'essaie de faire un ls recursif( la celebre commande ls -R sous linux), j'ai reussi a faire le ls de base(sans recursivite) mais tout ce complique qd j'essaie le recursif!
help me!!!!!!
#include<stdio.h>
#include<dirent.h>
#include<sys/types.h>
#include<stdlib.h>
#include<string.h>


int regFlag=0; //drapeau pour l'option -R

//fonction non utilise pour l'instant , le test d'option est fait directement ds le main
//char *parseArgs(int argc,char **argv){
//if ((argv[1][0]=='-')&&(argv[1][1]=='R')) regFlag=1;
//else {if (argc>=2) printf("mauvaise option");}
//return (argv[2]);
//}

//fonction qui concatene src et dest avec allocation de memoire
char *extendString(char *dest,const char *src){
if (!(dest=(char*)realloc(dest,(strlen(dest)+strlen(src)+1)*sizeof(char))))
{
puts("impossible d'allouer");
exit;
}
strcat(dest,src);
return(dest);
}

//fonction du ls recursif
int stdlistdir(const char* nameDir){
DIR *dir_stream;
char* entree;
struct dirent *dir_ent;

dir_stream=opendir(nameDir);
if (dir_stream==NULL){
printf("erreur de lecture");
exit;
}

while(1){
dir_ent=readdir(dir_stream);
if (regFlag==1){ //si l'option est activee...
entree=(char *)strdup(nameDir);
extendString(entree,"/");
extendString(entree,dir_ent->d_name);
strcat(entree,nameDir);
if (*dir_ent->d_name!='.')
printf("%s\n",dir_ent->d_name);
}
else if (*(dir_ent->d_name)!='.') //sinon
printf("%s\n",dir_ent->d_name);

}

closedir(dir_stream);
}

int main(int argc,char* argv[]){
//test si l'option est presente
if ((argv[1][0]=='-')&&(argv[1][1]=='R')) {
regFlag=1;
stdlistdir(argv[2]);
}
else stdlistdir(argv[1]);
getchar();
}

merci d'avance o toi grand sage de l'info lol

Meilleures réponses pour « ls recursif en C » dans :
Les templates en C++ Voir Introduction Avantages Inconvénients Quand utiliser des templates ? Que dois-je mettre dans les .hpp et dans les .cpp ? Convention de notations Quelques templates célèbres STL BGL Premiers pas Spécifications de templates Template par...
La compilation et les modules en C et en C++ VoirCet article a pour vocation d'introduire les notions de bases de la compilation en C et en C++ et de la programmation modulaire. Il permet de mieux comprendre les messages d'erreur du compilateur. Les notions abordées ici sont indépendantes du...
3D Secure / Verified by Visa / SecureCode: Qu'est-ce que c'est ? VoirDepuis octobre 2008, les banques et commerçants en ligne ont commencé à adopter le système 3DSecure pour les paiements sur Internet. Qu'est-ce que c'est ? 3DSecure est appelé "Verified by Visa" chez Visa, et "SecureCode" chez Mastercard. (Les logos...
[Langage C] C/C++ Erreur de segmentation VoirQu'est ce qu'une erreur de segmentation Vous êtes en train de développer une application sous Linux en C/C++. Tout va bien, ça compile, les oiseaux chantent. Donc vous lancez votre application pour la tester. Et vous obtenez l'un de ces deux...
Télécharger Visual C++ Express VoirVisual C++ Express est une version "gratuite" et allégée de Visual Studio ; l'utilisation requiert l'inscription sur le site de Microsoft. Cet environnement de développement permet de créer des application Win32 ou du .NET C.
Langage C++ - Les types de données VoirLes 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...
Les chaînes de caractères en C++ 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...
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...

1

Bob, le 13 nov 2003 à 11:10:36

Je donne ma langue au chat :-P . En tout cas il est pas beau ton code, pas assez aéré, les blocs ne sont pas clairement reconnaissables bref faudrait apprendre à faire de la mise en forme de code pour que ce soit le plus maintenable possible.

Répondre à Bob

2

bibiloute, le 13 nov 2003 à 11:12:12

Merci je sais le faire c parce que j'ai fait un copier coller qui m'a pas mit les tabulations!

Répondre à bibiloute

3

Bob, le 13 nov 2003 à 14:22:40

C'est même pas l'histoire des tabulations qui me gêne le plus mais les blocs, par exemple:

type ma_fonction(type argument) {
/* instructions */
}

une fonction toute simple pour identifier le bloc (début/fin) c'est déjà un peu la galère du à la lecture verticale d'instructions alors pour une imbrication voilà ce que ça donne:

type ma_fonction1(type argument) {
/* instructions */
type ma_fonction2(type argument) {
/* instructions */
type ma_fonction3(type argument) {
/* instructions */
}
}
}

je préfère de loin un style de ce genre qui me permet de mieux m'y retrouver:

type ma_fonction1(type argument)
{
/* instructions */
type ma_fonction2(type argument)
{
/* instructions */
type ma_fonction3(type argument)
{
/* instructions */
}
}
}

A savoir aussi faire des tabulations utiles car décaler c'est bien mais donner un sens au décalage c'est encore mieux. J'utilise la tabulation pour signaler un élément ou instruction imbriqué dans un bloc.

Exemple:

...
{
[tab]/* instruction */
[tab]{
[tab][tab]/* instruction */
[tab]}
}
...

Avec cette méthode je suis quasi-certain de jamais me planter sur la fermeture d'un bloc car il suffit de lire à la verticale les accolades pour savoir si un bloc n'a pas été fermé.

Répondre à Bob

4

tafiscobar, le 13 nov 2003 à 20:18:40

Je n et'ecrirais pas le code, car je n'ai pas le temps, et puis ce que j'vais fait etait plus court que ce que t'as fait, mais je ne sais plus ou je l'ai mis, voici le principe :

void lsr (char *dir) {
[tab] ouvrir dir et ts les tests qui s'en suivent;
[tab] while ((entree = readdir(dir))!=null) {
[tab] if( isdir(entree)) lsr ( entree);
[tab] else printf (entree);
[tab]}
}
voilou un pseudo code, mi-C mi-Français.
Le principe du recursif c'est de s'appeler soi-meme et de s'arreter avec une condition d'arret. Or ds ta fct je ne vois aucun appel a lui-meme.
J'espere t'avoir aide.


tafiscobar

Répondre à tafiscobar

6

bibiloute, le 13 nov 2003 à 21:04:03

Merci c deja un debut l'algo
ms tu peux preciser pour le test if(isdir(entree)) qu'est ce que tu cherchea tester ou qu'est ce que isdir?
merci

Répondre à bibiloute

7

tafiscobar, le 14 nov 2003 à 13:14:01

Comme son nom l'indique, il te retourne vrai si l'entree donne en argument est un repertoire ou non, je ne me rappelle pas qu'elle existe, en fait il doit y avoir ds les champs de la structure DIR, un champ type qui specifie si c'est un lien, ou un fichier simple ou un repertoire, etc... je pense qu'il s'appelle DT_DIR. En fait le test if(isdir(entree)) c'est eqyuivalent a ca:
if(entree->d_type == DT_DIR) lsr(strcpy(malloc(strlen(entree->dir)*sizeof(char)),entree->d_name));

tafiscobar

Répondre à tafiscobar

5

Bob, le 13 nov 2003 à 20:25:39

Je vais te tirer les zoreilles tafiscobar :-D .

Répondre à Bob

8

batmat, le 15 nov 2003 à 00:26:32

Salut,

void disp_dir(char* dirpath)//, int rec, char onebylinemode, char longformat)
{	DIR* dirtolist = NULL;
	struct dirent* d_filename = NULL;
	
	if ( dirpath==NULL)
	{
		fprintf(stderr, "Erreur : nom de répertoire passe NULL\n");
		exit(1);
	}
	if( opendir(dirpath)==NULL )
	{
		return ;
	}
	
	// ici, on sait qu'on a affaire à un répertoire, donc on le parcourt
	//récursivement
	if ( (dirtolist = opendir(dirpath)) == NULL )
	{
		perror("opendir ");
		exit(1);
	}
	
	while ( (d_filename = readdir(dirtolist)) != NULL )
	{
		
		/* affichage inconditionnel du nom de fichier ou de repertoire
		*/
		printf(" %s", d_filename->d_name);
		
		printf("\t");
		
		/* si on est en mode récursif et qu'on a un rep, on enregistre
		son nom pour le traiter ensuite */
		if( opendir(d_filename->d_name)!=NULL &&
		strcmp(d_filename->d_name,".")!=0 &&
		strcmp(d_filename->d_name,"..")!=0)
		{
			disp_dir( d_filename->d_name);
		}
	}
}


En gros, ça devrait marcher, j'ai ressorti un vieux tp :)

@++
Vous hésitez entre Linux et Windows ?
Vous voulez dépenser du temps ou de l'argent ?

Répondre à batmat

10

 bibiloute, le 15 nov 2003 à 12:47:12

Merci , en fait j'ai resolu mon probleme en grande partie en sachant aussi que opendir ne marche que sur des repertoires, ce qui simplifie granndement je vais qd meme comparer avec ton prog
tchao merci

Répondre à bibiloute

9

Bob, le 15 nov 2003 à 01:00:34

Oh! C'est beau O_O . Reste à savoir si ça marche vraiment, en tout cas je vois que je n'ai pas brailler pour rien :-D .

Répondre à Bob