2015-04-09 22 views
5

C programlamada çok yeniyim. Bir klasördeki tüm dosyalar arasında geçiş yapmak ve bu öznitelikler için her dosyayı yazdırmak için bu programa ihtiyacım var. Bu noktada sadece klasörün niteliklerini yazdırıyor.Bir dosya ve yazdırma dosya özniteliklerini döngü içinde C

#include <sys/types.h> 
#include <sys/stat.h> 
#include <stdlib.h> 
#include <stdio.h> 
#include <time.h> 
#include <dirent.h> 

int main(int argc, char *argv[]) 
{ 
    DIR *dp; 
    struct stat file_stats; 

    if (argc != 2) { 
     fprintf(stderr, "Usage: fstat FILE...\n"); 
     return EXIT_FAILURE; 
    } 

    if ((stat(argv[1], &file_stats)) == -1) { 
     perror("fstat"); 
     return EXIT_FAILURE; 
    } 

    dp = opendir("./"); 
    if (dp == NULL) { 
     perror("couldn't open directory"); 
     return EXIT_FAILURE; 
    } 

    while (readdir(dp)) { 
     printf("filename: %s\n", argv[1]); 
     printf(" device: %lld\n", 
       file_stats.st_dev); 
     printf(" protection: %o\n", 
       file_stats.st_mode); 
     printf(" number of hard links: %d\n", 
       file_stats.st_nlink); 
     printf(" user ID of owner: %d\n", 
       file_stats.st_uid); 
     printf(" group ID of owner: %d\n", 
       file_stats.st_gid); 
     printf(" device type (if inode device): %lld\n", 
       file_stats.st_rdev); 
     printf(" total size, in bytes: %ld\n", 
       file_stats.st_size); 
     printf(" blocksize for filesystem I/O: %ld\n", 
       file_stats.st_blksize); 
     printf(" inode number: %lu\n", 
       file_stats.st_ino); 
     printf(" time of last access: %ld : %s", 
       file_stats.st_atime, 
       ctime(&file_stats.st_atime)); 
     printf(" time of last change: %ld : %s", 
       file_stats.st_ctime, 
       ctime(&file_stats.st_ctime)); 
     closedir(dp); 
    } 

    return EXIT_SUCCESS; 
} 

Ben ise döngüye yapı devam etmeliyiz ama derleyici diyor bunu yaparken "bildirilmemiş file_stats."

cevap

1

Eğer döngü içindeyken

if((stat(ep->d_name, &file_stats)) == -1) { 
    perror("fstat"); 
    return 1; 
    } 

çağırmalıdır.

+0

onun da '' döngüde closedir() çağırır olduğunu fark ettiniz mi? Dışarıda olmamalı, "0" dan (main) geri dönmeden hemen önce mi? –

+1

Doğru! Ne yazık ki test etmek için bir posix makinem yok, bu yüzden sadece bulduğum ilk hatayı işaret ettim. Aslında 'printf (" dosya adı:% s \ n ", argv [1]);' printf ("filename:% s \ n", ep-> d_name); "ve yerine" dp = opendir ("./"); 'dp = opendir (argv [1]);' modunun mantıklı görünmesini sağlar. –

+0

Kesinlikle haklısınız! Programı (Linux makinemde) değişikliklerinizle kontrol ettim ve şimdi doğru şekilde çalışıyor. Tamamen doğru bir çalışma koduna sahip olmak için cevabımı ekleyeceğim. –

3

Valentin'in cevabına ek olarak, closedir() döngüsünden de çıkmalısınız.

GÜNCELLEME: Ayrıca gerçek dosya hakkında bilgi edinmek için stat(ep->d_name, ...) ile stat(argv[1], ...) değiştirmeniz gerekiyor. Ancak bundan önce argv[1] dizinine girmeniz gerekir (chdir() sistem çağrısı kullanarak).

Tamamen çalışma kodu:

#include <sys/types.h> 
#include <sys/stat.h> 
#include <stdlib.h> 
#include <stdio.h> 
#include <time.h> 
#include <dirent.h> 
#include <unistd.h> 

int main(int argc, char *argv[]) 
{ 
    DIR *dp; 
    struct stat file_stats; 
    struct dirent *ep; 
    int ret = EXIT_SUCCESS; 
    int ret2; 

    if (argc != 2) { 
     fprintf(stderr, "Usage: %s FILE...\n", argv[0]); 
     return EXIT_FAILURE; 
    } 

    dp = opendir(argv[1]); 
    if (dp == NULL) { 
     perror("Couldn't open directory"); 
     return EXIT_FAILURE; 
    } 

    ret2 = chdir(argv[1]); 
    if (ret2 == -1) { 
     perror("Unable to change directory"); 
     ret = EXIT_FAILURE; 
     goto out1; 
    } 

    while ((ep = readdir(dp))) { 
     printf("filename: %s\n", ep->d_name); 

     if ((stat(ep->d_name, &file_stats)) == -1) { 
      perror("fstat"); 
      ret = EXIT_FAILURE; 
      goto out2; 
     } 

     printf(" device: %lld\n", 
       file_stats.st_dev); 
     printf(" protection: %o\n", 
       file_stats.st_mode); 
     printf(" number of hard links: %d\n", 
       file_stats.st_nlink); 
     printf(" user ID of owner: %d\n", 
       file_stats.st_uid); 
     printf(" group ID of owner: %d\n", 
       file_stats.st_gid); 
     printf(" device type (if inode device): %lld\n", 
       file_stats.st_rdev); 
     printf(" total size, in bytes: %ld\n", 
       file_stats.st_size); 
     printf(" blocksize for filesystem I/O: %ld\n", 
       file_stats.st_blksize); 
     printf(" inode number: %lu\n", 
       file_stats.st_ino); 
     printf(" time of last access: %ld : %s", 
       file_stats.st_atime, 
       ctime(&file_stats.st_atime)); 
     printf(" time of last change: %ld : %s\n", 
       file_stats.st_ctime, 
       ctime(&file_stats.st_ctime)); 
    } 

out2: 
    ret2 = chdir(".."); 
    if (ret2 == -1) { 
     perror("Unable to change directory back"); 
     ret = EXIT_FAILURE; 
     goto out1; 
    } 

out1: 
    closedir(dp); 
    return ret; 
} 
+0

Bu neredeyse işe yarıyor. Komut ./program dosyaları ile çalıştırdığımda, sadece "files" dizini hakkındaki bilgileri yazdırıyor. Bu yüzden aynı bilgiyi 8 kez basıyorum. Programı yanlış çalıştırıyorum. – MikeT

+0

@MikeT İyi yakalama! Çünkü stat (argv [1], '' yapıyorsunuz, bu yüzden argv [1] 'de dizin hakkında bilgi ediniyorsunuz. Cevabımdaki sorunu çözeceğim, bana bir dakika vereceğim –

+0

@MikeT, tamam, cevabımdaki kodu düzelttim, şimdi doğru çalışıyor .. –