panthere007
Messages postés20Date d'inscriptionvendredi 18 avril 2008StatutMembreDernière intervention 7 août 2009
-
8 avril 2009 à 03:09
panthere007
Messages postés20Date d'inscriptionvendredi 18 avril 2008StatutMembreDernière intervention 7 août 2009
-
12 avril 2009 à 03:32
Hello,
Merci de me lire,
excuser l'indentation des commentaires mai le copier coller déconne
pour le bug c'est simple c'est expliquer aux début du fichier
noter que je débute,depuis peux que je compile avec g++ j'utilise geany comme éditeur.
ce code est fonctionnel hormis le fait qu'il ne fait pas ce que je veux
Curieux il n'y a pas le moyen de coller son code ?
code
Ce code est destiner a lister le plus rapidement possible.
Les fichier et les répertoire sous linux.
Avec leur atribbus aux complet.
*/
/*
Les répertoires ce présente comme ceci.
note: remplacer le ~ par celui de votre utilisateur.
mkdir -p ~/rep_racine/rep1
mkdir -p ~/rep_racine/rep2/sous_rep_2_0
mkdir -p ~/rep_racine/rep2/sous_rep_2_1
mkdir -p ~/rep_racine/rep2/sous_rep_2_2
mkdir -p ~/rep_racine/rep2/sous_rep_2_3
mkdir -p ~/rep_racine/rep3
mkdir -p ~/rep_racine/rep2/sous_rep_2_3/sous_sous_rep2
*
le dernier répertoir n'est pas trouver alors que ceux situer dans ~/rep_racine/rep2/ le son
*/
int main()
{
//variable
std::vector<std::string> search_full_path; //retourne un tableau chemin complet de tout les répertoires trouver
std::vector<std::string> search_rep_name; //repertoir seulement,pas encore utilisée
std::vector<std::string> search_file_name; //fichier seulement,pas encore utilisée
std::vector<std::string> stat_info; //information global sur le répertoir ou le dossier,pas encore utilisée
std::string transfere; //variable pour le nom du repertoir en recusiviter, passe en paramettre le répetoire racine.
//code
search_full_path.push_back("/home/taz/rep_racine/"); //valeur par defaut,en cour de dévloppment,rarement utiliser
transfere = "/home/taz/rep_racine";
Full_Search(search_full_path, search_rep_name, search_file_name, stat_info,transfere);
std::cout << "nombre d'élément apres execution " << search_full_path.size() << std::endl; //affiche le nombre d'entrée du tableau
for (long i = 0; i < search_full_path.size(); ++i ) //affiche le contenu du tableaux
{
std::cout << search_full_path[i] << std::endl;
}
std::cout << "affichage terminer" << std::endl;
return 0;
} // main
cs_rt15
Messages postés3874Date d'inscriptionmardi 8 mars 2005StatutModérateurDernière intervention 7 novembre 201413 8 avril 2009 à 15:35
Salut,
[quote=panthere007]
Ce code est destiner a lister le plus rapidement possible.
/quote
Le plus rapidement possible ?
Alors tu n'emploies pas du tout la bonne méthode.
td::vector<string> -> string est lent. vector est lent. Combiné les deux c'est affreusement lent.
Et imagine que ton répertoire contienne 10000 répertoires ? Tu fait un vector de 10000 strings ?
Tu as une idée de la consommation mémoire ?
Bref, tu n'iras pas bien loin avec ce genre d'algo.
D'une manière générale quand on veut :
1) Récupérer un ensemble d'objets quelconques.
2) Appliquer un algo sur chacun d'entre eux.
Il ne faut pas essayer de lister ces objets puis parcourir ces objets.
Il faut faire le traitement a chaque objet lors du parcourt. C'est infiniment plus efficace.
Mais on voudrait ne pas avoir à réécrire l'algo de parcourt pour tous les traitements possibles.
Le copier coller, c'est mal.
On va donc faire une fonction de parcourt qui prend en argument une fonction (on appelle ça une callback) de traitement.
Comme ça la fonction de parcourt va appeler la fonction de traitement pour tous les élements parcouru.
Sans faire de liste ni autre structure mémoire aussi consommatrice de RAM que lente car allouée dynamiquement.
Voilà un exemple de code.
C'est du C. Ou du C++. Comme tu veux. Mais pour faire du "plus rapidement possible", je t'invite vivement à oublier le C++.
<hr size="2" width="100%" />#include <stdio.h>
#include <dirent.h>
#include <string.h>
/* Fonction callback appelée lors de l'énumération */
typedef int (*enum_dir_callback)(char *lpDirPath);
/*
* Utilisée par EnumDir pour pouvoir transmettre un buffer en paramètre
* et ainsi ne pas surchrager la pile.
*/
int EnumDirInternal(char *lpDirPath, enum_dir_callback lpCallback, char* lpBuffer)
{
DIR *lpDir; /* Le répertoire courant */
struct dirent *lpChild; /* Un fils du répertoire */
int bContinue; /* Continuer l'énumération ? */
bContinue = 1;
lpDir = opendir(lpDirPath);
/* Si c'est un répertoire */
if (lpDir)
{
/* Appel de la fonction utilisateur */
if (! lpCallback(lpDirPath))
bContinue = 0;
else
{
/* On récupère . et .. */
readdir(lpDir);
readdir(lpDir);
/* Pour tous les fils */
while (1)
{
lpChild = readdir(lpDir);
if (! lpChild) break;
/* Construction d'un chemin complet vers le fils */
strcpy(lpBuffer, lpDirPath);
strcat(lpBuffer, "/");
strcat(lpBuffer, lpChild->d_name);
/*
* Appelle lpCallback pour lpDirPath et tous ses sous répertoires.
* Arrête l'énumération si lpCallback renvoie 0.
*/
int EnumDir(char *lpDirPath, enum_dir_callback lpCallback)
{
char lpFullPath[4096];
panthere007
Messages postés20Date d'inscriptionvendredi 18 avril 2008StatutMembreDernière intervention 7 août 2009 9 avril 2009 à 00:54
Merci pour ta réponse très constructives :)
Je ne connaissait pas les callback, je vai me panchez dessus
j'ai essayer ton code telle qu'elle , 2 bug voici la première erreur:
surf_find_file_main.cpp: In function ‘int main()’:
surf_find_file_main.cpp:80: warning: deprecated conversion from string constant to ‘char*’
./
./.
la 2eme j'ai change le chemin dans le main par /home/user/rep_racine user étant l'utilisateur et j'obtien
line 10: 5329 Erreur de segmentation
note je compile avec g++ ton code rassemble surtout a du C et pas du C++ (excuse pour la confusion c'est lier aux fait que j'utilise cout et pas printf.
Avec quoi l'a tu compiler ? gcc ?
cs_rt15
Messages postés3874Date d'inscriptionmardi 8 mars 2005StatutModérateurDernière intervention 7 novembre 201413 9 avril 2009 à 10:09
Avec quoi l'a tu compiler ? gcc ?
Avec les deux en fait.
warning: deprecated conversion from string constant to 'char*'
Mais je n'ai pas eu ce warning. D'après le net, il n'apparait pas sur des versions anciennes. Il est en fait dû au fait que mon "." passé en paramètre de EnumDir est en lecture seule, et donc qu'il ne peut pas être passé en paramètre d'une fonction qui attend un char*. Il faut changer une ou deux signatures en ajoutant const.
line 10: 5329 Erreur de segmentation
Probablement un dépassement des 4096 caractères du tampon. Non pas que tu ais (Ou pas) un chemin de 4096 caractères dans ton home, il y a un bug dans mon source.
En effet, lors de l'appel à EnumDirInternal(lpBuffer, lpCallback, lpBuffer), lpBuffer était modifié pour ajouté un fils, ce qui modifiait aussi le lpDirPath puisqu'ils sont les mêmes lors de cette appel. Bilan cela concaténait le fils 1 avec le fils 2 et ainsi de suite. Donc ça ne listait pas la moitié des répertoires et ça faisait des chemins beaucoup trops longs -> d'où l'erreur de segmentation je pense.
Donc il faut remonter d'un répertoire en sortie d'appel à EnumDirInternal.
Voilà qui devrait aller mieux :
<hr size="2" width="100%" />#include <stdio.h>
#include <dirent.h>
#include <string.h>
/* Fonction callback appelée lors de l'énumération */
typedef int (*enum_dir_callback)(const char *lpDirPath);
/*
* Utilisée par EnumDir pour pouvoir un premier caractère non const.
*/
int EnumDirInternal(char *lpDirPath, enum_dir_callback lpCallback)
{
DIR *lpDir; /* Le répertoire courant */
struct dirent *lpChild; /* Un fils du répertoire */
int bContinue; /* Continuer l'énumération ? */
bContinue = 1;
lpDir = opendir(lpDirPath);
/* Si c'est un répertoire */
if (lpDir)
{
/* Appel de la fonction utilisateur */
if (! lpCallback(lpDirPath))
bContinue = 0;
else
{
/* On récupère . et .. */
readdir(lpDir);
readdir(lpDir);
/* Pour tous les fils */
while (1)
{
lpChild = readdir(lpDir);
if (! lpChild) break;
/* Construction d'un chemin complet vers le fils */
strcat(lpDirPath, "/");
strcat(lpDirPath, lpChild->d_name);
/*
* Appelle lpCallback pour lpDirPath et tous ses sous répertoires.
* Arrête l'énumération si lpCallback renvoie 0.
*/
int EnumDir(const char *lpDirPath, enum_dir_callback lpCallback)
{
char lpPath[4096];
panthere007
Messages postés20Date d'inscriptionvendredi 18 avril 2008StatutMembreDernière intervention 7 août 2009 10 avril 2009 à 23:26
merci pour ta réponse, ma sa bug toujours :s
voila un extrait de la sortie le ~ = /home/tonuser
~/rep_racine/rep3/./././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././sous_rep3_2_2
sa me fait pareil si je mai le répertoire /home donc je doit dire que j'ai un peux de pain a suivre
Vous n’avez pas trouvé la réponse que vous recherchez ?
cs_rt15
Messages postés3874Date d'inscriptionmardi 8 mars 2005StatutModérateurDernière intervention 7 novembre 201413 11 avril 2009 à 08:51
Hein ???
Eventuellement, il peut y avoir un problème avec une arborescence récursive, c'est à dire un link avec un répertoire parent. Mais ta sortie est bizarre.
Tu as essayé sur une arborescence de répertoires plus simple ?
Au vu de la sortie, peut être que "." et ".." ne sont pas les deux premiers répertoires listés... Essaie de remplacer EnumDirInternal par cette fonction (Non testée) :
/*
* Utilisée par EnumDir pour pouvoir un premier caractère non const.
*/
int EnumDirInternal(char *lpDirPath, enum_dir_callback lpCallback)
{
DIR *lpDir; /* Le répertoire courant */
struct dirent *lpChild; /* Un fils du répertoire */
int bContinue; /* Continuer l'énumération ? */
bContinue = 1;
lpDir = opendir(lpDirPath);
/* Si c'est un répertoire */
if (lpDir)
{
/* Appel de la fonction utilisateur */
if (! lpCallback(lpDirPath))
bContinue = 0;
else
{
/* Pour tous les fils */
while (1)
{
lpChild = readdir(lpDir);
if (! lpChild) break;
if (! strcmp(lpChild->d_name, ".") continue;
if (! strcmp(lpChild->d_name, "..") continue;
/* Construction d'un chemin complet vers le fils */
strcat(lpDirPath, "/");
strcat(lpDirPath, lpChild->d_name);
panthere007
Messages postés20Date d'inscriptionvendredi 18 avril 2008StatutMembreDernière intervention 7 août 2009 12 avril 2009 à 03:32
merci pour ta réponse , j'ai pas essayer t'a denière méthode methode, mai je m'en suis inspirer.
le code que je fourni ici fonctionne chez moi, note que le tableau de type vector est facultatif. sinon sa tourne bien.