• 0
مومو (momo)

[ تمت الإجابة ]سؤال : عن تصفح المجلدات و الملفات مع dirent.h

سؤال

السلام عليكم

حياكم الله أعضاء المنتدى و سدد خطاكم

أتمنى أن أجد حلا لهذه المشكلة

#include <stdlib.h>
#include <stdio.h>
#include <dirent.h>
#ifndef WIN32
#include <sys/types.h>
#endif

typedef struct dirent* fichier;

int main(void)
{
DIR* rep = NULL;
fichier f=NULL;
rep = opendir("C:\\Documents and Settings\\MOMO\\My Documents\\Downloads\\momo");
if (rep == NULL)
{
perror("erreur:");
exit(1);
}
puts("Le dossier a ete ouvert avec succes");
while ((f = readdir(rep)) != NULL)
printf("Le fichier lu s'appelle '%s'\n", f->d_name);
if (closedir(rep) == -1)
exit(-1);
puts("Le dossier a ete ferme avec succes");
return EXIT_SUCCESS;
}

W1Bf1.jpg

السؤال كالتالي :

ماذا يعني الملف '.' و الملف الآخر '..' وما الفائدة من وجودهما؟؟

xzyt2.jpg

من لديه فكرة عن هذين الملفين فلا يبخل علينا بالشرح و لو كان شرحا مطولا وشكرا مسبقا blush.gif

1

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

10 إجابة على هذا السؤال .

  • 0

. تعني المجلد الحالي

.. تعني المجلد الأب

تم تعديل بواسطه ahmed_youssef
2

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

أهلا أستاذ ahmed_youssefsmile.gif

. تعني المجلد الحالي

.. تعني المجلد الأب

هذه الإجابة تكررت على مسامعي أكثر من مرة ولكن المشكلة التي لم أفهمها كيف لمجلد مثلا أن يحتوي على مجلد حالي وعلى مجلد أب؟huh.gif

صراحة اختلطت علي الأمور شيئا ما ولا زلت أجد غموضا في فهم المسألة؟؟ wacko.gif

تم تعديل بواسطه مومو (momo)
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

أهلا أخي مومو laugh.gif ، يا له من تواضع منك أخي smile.gif

إذا قمت أنت بوضع أسئلة تحتاج إلى أجوبة فماذا سأفعل أنا إذن ، هل أستسلم لضعفي أمامك ؟؟ sad.gif

المهم ، أنه لدي ما تريده ، لأنني و لحسن حظك كنت أبحث في هذا الموضوع هذه الأيام ...

الكود الذي حاولت كتابته ، يحاكي هذا الكود الذي يعمل في Borland C smile.gif


#include <stdio.h>
#include <dir.h>
#include <conio.h>

int main()
{
struct ffblk Files;
int finish;
printf("Directory listing of *.*\n");
finish = findfirst("*.*",&Files,0);
while (!finish)
{
printf(" %s\n", Files.ff_name);
finish = findnext(&Files);
}
getch();
return 0;
}

أي أن البرنامج يبحث عن الملفات المجاورة له في نفس المسار ...

لكن إن أردت تصفح المجلدات و البحث فيها ، فستظطر إلى استخدام ما يسمى بالبحث التراجعي Recursive Search File in Directories

لكن ستصادفك هذه المشكلة ، ليست مشكلة في الحقيقة لكنها تشوه مظهر البرنامج،

ستظهر لك نقطة و بعدها 2 نقاط ،،،

. : Curent Directory

.. : Parent Directory

ولكي تعرف تفرق بينها و بين الملفات ، ضع شرطا يتأكد من ما إذا كانت تقبل الفتح

فإن كانت كذلك في مجلدات و إلا فإنها ملفات ،،،

ولكي يتضح لك الأمر ، إليك مثالا وجدته البارحة عندما كنت أبحث عن طريقة للبحث في كل

المجلدات ، أتمنى أن تفيدك smile.gif


/* DIRTREE.C V 1.0 by Glen E. Gardner, Jr. */
/* A recursive directory tree traversal that finds the path and names */
/* for all files in the specified path. */

/* this program was written and compiled using Borland C++ 5.0 on */
/* Microsoft Windows NT 4.0 */
/* The program was written with no MS API function calls, for as much */
/* OS independence as was practical. */
/* It should compile and run on DOS, Win 3.X , Win 95/98 and Win NT. */

/* This program was written in ansi C as much as was possible, UNIX users might */
/* find this program easy to port. */


#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
#include <dir.h>
#include <string.h>

int scandir(char *,char *);
int getsize(char *);
void doit(char *);
int scanstring(char *,char *);

int main(int argc,char *argv[])
{
chdir(argv[1]);
if (argc != 2)
{
printf("usage: DIRTREE <PATH>\n");
exit(1);
}
doit(".");
exit(0);
}

int getsize(char *dirname)
{/* finds and returns the size of the directory entry (in bytes) */

DIR *dir;
struct dirent *ent;
int size=0;


if ((dir = opendir(dirname)) == NULL)
{
perror("Unable to open directory");
return(NULL);
}
while ((ent = readdir(dir)) != NULL);
rewinddir(dir);
while ((ent = readdir(dir)) != NULL)size=size+sizeof(ent->d_name)+1;

if (closedir(dir) != 0)
perror("Unable to close directory");
return(size);
}


int scandir(char *dirname,char *entries)
{/* scan the directory and store the entries in a buffer */
DIR *dir;
struct dirent *ent;
int count=1;
char name[256];

if ((dir = opendir(dirname)) == NULL)
{
perror("Unable to open directory");
return(0);
}

while ((ent = readdir(dir)) != NULL)count++;

rewinddir(dir);

while ((ent = readdir(dir)) != NULL)
{
strcpy(name,ent->d_name);
sprintf(entries,"%s",name);
entries=entries+strlen(name)+1;
count++;
}

if (closedir(dir) != 0)
perror("Unable to close directory");

return(count);
}


void doit(char *dirname)
{/* scan the buffer and recursively enter any directories found */

int size;
char *entries;
char name[256];
char Path[256];
char *path;
char oldpath[256];
char old[256]="none";
FILE *filein;
path=Path;
size=getsize(dirname);
entries=(char *)malloc(size);
scandir(dirname,entries);
getcwd(Path,256);
strcpy(old,Path);

while(scanstring(name,entries)!=EOF)
{

/* store the path for use later */
getcwd(Path,256);
if((strcmp(name,"."))&&(strcmp(name,"..")))
{

/* this is where the valid path variable can be found */
if(!strcmp(Path,old))printf("PATH: %s\n",Path);
strcpy(oldpath,Path);

/* add the next entry to the path for testing */
strcat(Path,"\\");
strcat(Path,name);

/* see if the entry is a file */
/* here is where the valid filename associated with the path can be found */
if((filein=fopen(Path,"r"))!=0)
{
printf("NAME: %s\n",name);
fclose(filein);
}
else
{
if(chdir(Path)==0)
{/* if the entry is a valid directory, go there */
getcwd(path,256);

/* start the recursive traversal */
doit(".");

/* restore the path */
strcpy(Path,oldpath);
chdir(Path);
getcwd(path,256);
}
}
/* set the sentinel variable for state changes */
strcpy(old,Path);
strcpy(Path,oldpath);
chdir(Path);
getcwd(path,256);
}

entries=entries+strlen(name)+1;
}

return;
}

int scanstring(char *string,char *buffer)
{
int i;
int size;
char *temp;

size=0;
temp=buffer;
while(*buffer!=NULL)
{
size++;
buffer++;
}

buffer=temp;

for(i=0;i<=size;i++)
{
*string=*buffer;
buffer++;
string++;
}
*string=*buffer;
buffer=buffer-2;

if(*buffer==NULL)return(EOF);
return(size);
}

1

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

أهلا حمزةhappy.gif

إذا قمت أنت بوضع أسئلة تحتاج إلى أجوبة فماذا سأفعل أنا إذن ،

ستجيب عليها !! laugh.gif

لكن إن أردت تصفح المجلدات و البحث فيها ، فستظطر إلى استخدام ما يسمى بالبحث التراجعي Recursive Search File in Directories

لكن ستصادفك هذه المشكلة ، ليست مشكلة في الحقيقة لكنها تشوه مظهر البرنامج،

ستظهر لك نقطة و بعدها 2 نقاط ،،،

. : Curent Directory

.. : Parent Directory

إذا أمكنك أخي حمزة أن تتعمق قليلا في شرح البحث التراجعي Recursive Search File in Directories الذي تحدث عنه بأسلوبك الخاص لأنه ليس لدي أدنى فكرة عنهblush.gif

أنا سأحاول أن أعطيك الفكرة التي كونتها سابقا عن كيفية تصفح الملفات داخل مجلد

وحاول أنت أن تجد لي نوع الخطأ الذي أقع فيه ولك أجر كبير عند اللهcool.gif

الإشكالية عندي :

المجلد يحتوي على ملفات (يمكن أن تكون ملفا (mp3,txt ..) أو مجلدا آخر )

و المجلد الحالي هو '.' أي كيف لمجلد أن يحتوي على نفسه؟؟wacko.gif وكيف يمكنه كذلك أن يحتوي على مجلد أب؟dry.gif

تمعن كلامي جيدا وحاول أن تكشف لي أخطائي و تقوم بتصحيحها happy.gif

+1

تم تعديل بواسطه مومو (momo)
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

السلام عليكم

طريقة عرض محتويات مُجلد ما تتعلق بمفهوم النظام الشجري أو التسلسل الهرمي للملفات, يُسمى هذا النظام بالــ FHS في Linux و هو احتصار لــ Filesystem Hierarchy.

في الــ Windows تتم الإشارة إلى أي مجلد من طرف الدليل الرأسي أو الجذر (Root Directory) حيث يُمثل هذا المجلد نقطة الدخول إلى أي مجلد آخر موجود في النظام. لذا إذا حاولت أي دالة الوصول إلى ملف معين, ستمر قبل ذلك بنقطة الدخول الرئيسية.

في Linux يكون الروت وحيداً حيث يتم تمثيله بالــ slash هكذا :

/usr/bin/folder

أما في الــ Windows فيُمكن وجود عدة ملفات رئيسية لأن كل partition تُمثل جذر.

يتم الفصل بين الملفات في الويندوز بالــ Antislash على عكس اللينكس.

1

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

كما قال أحمد, لو كنت في المسار :

C:\Users\MOMO

فسيكون قيمة . و .. الآن:

.  = C:\Users\MOMO  # المسار الذي تتواجد فيه الآن
.. = C:\Users\ # المسار السابق

تستطيع إستخدامها مثلاً لو كتبت برنامج إسمه app.exe وملف file.txt ستضعهما في المسار bin ووضعت مجلد للصور إسمه images وداخله صورة إسمها background.png ووضعت كامل المجلدات داخل مجلد إسمه project:

         project
|
+-------+------------------+
| |
bin images
| |
app.exe, file.txt background.png

لو أردت الوصول للصورة background.png, فلايلزمك كتابة المسار الكامل لها, فقد لاتعرف أين وضع المجلد project, فقط إكتب :

fh = fopen("../images/background.png", "r");

وإذا أردت الوصول للملف file.txt فيمكنك عمل هذا بكتابة :

fh = fopen("./file.txt", "r");

سواء كنت على ويندوز أو لينكس يُمكنك إستخدام الشرطة المائلة /.

2

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

شكرا جزيلا أستاذ Mr.B على هذا الشرح الذي استفدت منه الشيء الكثير

تم تعديل بواسطه مومو (momo)
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

هل من مثال عن البحث التراجعي عن الملفات في لغة السي، و بإبداعات أناملك أستاذ Mr.B ؟

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

هذا مثال كتبته للبحث في شجرة الملفات (يحتاج لمزيد من العمل) :

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>

#ifndef MAX_PATH
#define MAX_PATH 260
#endif

void mycallback(char *path);

int search_walk(char *path, void (*callback)(char*));
int search_isspecial(char *path);

int main(int argc, char **argv)
{
search_walk(".", mycallback);
return 0;
}

int search_walk(char *path, void (*callback)(char*))
{
DIR *directory = NULL;
struct dirent *content = NULL;
char fullpath[MAX_PATH] = {0};

if( (directory = opendir(path)) == NULL )
return -1;

while( (content = readdir(directory)) != NULL ) {
if( !search_isspecial(content->d_name) ) {
callback(fullpath);
snprintf(&fullpath[0], MAX_PATH -1, "%s/%s", path, content->d_name);
search_walk(fullpath, callback);
}
}

closedir(directory);
return 0;
}

int search_isspecial(char *path)
{
return (strcmp(path, ".") == 0) || (strcmp(path, "..") == 0);
}

void mycallback(char *path)
{
puts(path);
}

  • البرنامج سيبحث عن الملفات في المسار الحالي ".".
  • تأخذ الدالة search_walk مؤشر لدالة سيمرر لها المسار الكامل. وضعت الدالة mycallback لطباعة هذا المسار. يُمكنك تعديلها إذا أردت مطابقة جزء من المسار مثلاً لتصبح :
    void mycallback(char *path)
    const char *lookup = "file.txt";
    unsigned int llookup = strlen(lookup);

    while( (*path++ != '\0') && (strlen(path) >= llookup) ) {
    if( strncmp(path, lookup, llookup) == 0 ) {
    printf("%s\n", path);
    }
    }
    }


  • تبحث الدالة في المسارات الفرعية بإعادة إستدعاء نفسها.

لكن البحث بهذه الطريقة غير مجدي, من الأفضل إستخدام العمليات المتعددة threading عند البحث لأنه بطيئ.

1

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

  • يستعرض القسم حالياً   0 members

    لا يوجد أعضاء مسجلين يشاهدون هذه الصفحة .