2015-04-09 9 views
5

Sono molto nuovo alla programmazione in C. Ho bisogno di questo programma per scorrere tutti i file in una cartella e stampare questi attributi per ogni file. A questo punto sta stampando gli attributi della sola cartella.loop attraverso un file e stampa attributi di file in 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; 
} 

Penso di aver bisogno di spostare la struct nel ciclo while, ma quando faccio che il compilatore dice "file_stats non dichiarato."

risposta

1

si dovrebbe chiamare

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

all'interno del ciclo while.

+0

Avete notato che anche lui invoca 'closedir()' nel ciclo? Non dovrebbe essere fuori, appena prima di tornare a '0' da' main() '? –

+1

Giusto! Sfortunatamente non ho una macchina posix da testare, quindi ho puntato solo sul primo errore che ho trovato. In realtà 'printf (" nomefile:% s \ n ", argv [1]);' anche dovrebbe essere sostituito da 'printf (" nomefile:% s \ n ", ep-> d_name);' e invece di 'dp = opendir ("./"); 'guarda' dp = opendir (argv [1]); 'essere in modalità sensibile. –

+0

Hai assolutamente ragione! Ho controllato il programma (sulla mia macchina Linux) con le tue modifiche e ora funziona correttamente. Lo aggiungerò alla mia risposta per avere un codice di lavoro completamente corretto. –

3

Oltre alla risposta di Valentin, è necessario spostare closedir() fuori dal ciclo.

UPDATE: anche è necessario sostituire stat(argv[1], ...) con stat(ep->d_name, ...) per ottenere informazioni sui file vero e proprio. Ma prima è necessario inserire la directory argv[1] (usando la chiamata di sistema chdir()).

codice completamente di lavoro:

#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

Questo funziona quasi. Quando corro con il comando ./program files sta stampando solo le informazioni sulla directory "files". Quindi sto ottenendo la stessa informazione stampata come 8 volte. Sto eseguendo il programma in modo errato. – MikeT

+0

@MikeT Buona cattura! È perché stai facendo 'stat (argv [1], ...', quindi stai fondamentalmente ottenendo informazioni sulla directory in 'argv [1]'. Lo sistemerò nella mia risposta, dammi un minuto –

+0

@MikeT, ok, ho corretto il codice nella mia risposta, ora funziona correttamente –