LinuxForum.Fans
Тема

Помогите разобраться с кодом на С

Автор: XliN 5 сообщений 2127 просмотров
#99008

Есть код... отрыл в инете. Все вроде понятно, но не хватает знаний понят его полностью.

Показать
text
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <dirent.h>
 
#define DIRNAME "."
#define OFNAME  "out.log"
 
int main(void)
{
    FILE *ofp;
    DIR *dp;
    struct dirent *dent;
 
    if( (dp = opendir(DIRNAME)) == NULL) {
        fprintf(stderr, "opendir: %s: %s\n", DIRNAME, strerror(errno));
        return 1;
    }
    if( (ofp = fopen(OFNAME, "w")) == NULL) {
        fprintf(stderr, "fopen: %s: %s\n", OFNAME, strerror(errno));
        return 1;
    }
 
    while(dent = readdir(dp))
        if(strcmp(".", dent->d_name) && strcmp("..", dent->d_name))
            fprintf(ofp, "%s\n", dent->d_name);
    closedir(dp);
    fclose(ofp);
    return 0;
}

Не понятно как тут работает цикл while. Вижу что сравнивает "." с dent->d_name, но чет не вьеду в это. И что это за d_name. Подскажите. Я ламер и прошу не пинать ))

UPD: Мне нужно сделать программу, которая будет выдавать список всех файлов, которые были изменены за нужное мне число. Ну и где находятся они соответственно в громадном дереве директорий. Типо того.

#99230

Вот как-то так...

text
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <dirent.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <time.h>

#define DIRNAME "."

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

if ((dp = opendir(dir)) == NULL) { fprintf(stderr, "Can not open directory: %s\n", dir); return; } chdir(dir); while ((entry = readdir(dp)) != NULL) { lstat(entry->d_name, &statbuf); if (S_ISDIR(statbuf.st_mode)) { if (strcmp(".", entry->d_name) == 0 || strcmp("..", entry->d_name) == 0) continue; showfiles(entry->d_name, depth + 4); } else { if (S_ISBLK(statbuf.st_mode)||S_ISCHR(statbuf.st_mode)) continue; else { char *s_time = ctime(&statbuf.st_mtime); fprintf(stdout,"FileName = %s, Modification date = %s\n", entry->d_name, s_time); } } } chdir(".."); closedir(dp); }

int main(void) {

showfiles((char *)DIRNAME, 0);

return 0; }

Тут осталось добавить аргументы в main: имя каталога, от которого начинается чтение (в двнный момент используется текущий - #define DIRNAME ".") и дату модификации, передать их в функцию showfiles, где сравнивать с датой модификации текущего файла и печатать его название при совпадении. Если непонятно что-то, обращайтесь

З.Ы. Да, забыл еще, что вывод нужно, видимо, сделать с полным именем файла, типа

text
        
char *cwd = get_current_dir_name();
fprintf(stdout,"FileName = %s/%s, Modification date = %s\n", cwd, entry->d_name, s_time);
#99453

примечание есть в man 3 readdir

NOTES
Only the fields d_name and d_ino are specified in POSIX.1-2001. The remaining fields are available on
many, but not all systems. Under glibc, programs can check for the availability of the fields not defined
in POSIX.1 by testing whether the macros _DIRENT_HAVE_D_NAMLEN, _DIRENT_HAVE_D_RECLEN, _DIRENT_HAVE_D_OFF,
or _DIRENT_HAVE_D_TYPE are defined.

т.ч. не везде это сработает...
хотя нет, везде, что-то я перепутал. как раз d_name будет работать везде.

в том-же мане сказано:

On Linux, the dirent structure is defined as follows:

struct dirent {
ino_t d_ino; /* inode number */
off_t d_off; /* offset to the next dirent */
unsigned short d_reclen; /* length of this record */
unsigned char d_type; /* type of file; not supported
by all file system types */
char d_name[256]; /* filename */
};

из чего следует, что d_name просто имя файла. максимум 255 байтов (не букв! по русски это будет всего 127). В Windows несколько больше, потому файлы оттуда иногда не влезают в Linux.

#99466

Спасибо буду разбираться... еще раз убедился что С\C++ очень не четабельный язык :D
Тему прошу не закрывать. В плане еще маленькую GUI морду прилепить, но это после того, как разберусь с кодом.

UPD: Я чет стормозил, забыл что можно в man смотреть ))

Войдите или зарегистрируйтесь, чтобы ответить.