Search code examples
cdirectorystat

stat() function only works in the current directory C language


i'm using C on windows to read the contents of a directory and info about each entry, however the stat() function only works if i opened the current directory "."

directory = opendir(".")

whenever i try something like this "C:\Users\User\Desktop\programming" it does not work and outputs -1

directory = opendir("C:\\Users\\User\\Desktop\\programming")

can you pleas guide me here

#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <sys/stat.h>
void perror(const char *str);// for error detail 

int main()
{
    DIR *directory;
    struct dirent *file;
    struct stat info;
    int entries = 0 ;

    // entering the directory
    directory = opendir("C:\\Users\\User\\Desktop\\programming");//also C:\\Users\\User\\Desktop\\programming\\ didn't work
    if ( directory == NULL )
        {
            puts("the directory couldn't be accessed or does not exist");
          return(2);
        }


    printf("No   type         name              size           TimeStamp \n\n");
    while((file=readdir(directory))!= NULL)
    {

        entries++;

              //  problem : the stat is not working properly 
        stat(file->d_name,&info);
        if ((stat(file->d_name,&info)) == -1){
            printf("can't find %s\n", file->d_name);
            perror("ERROR");
           }
        // show the number of the entry
        printf("%2d  ",entries);

        // determine if file or directory
        if(S_ISDIR(info.st_mode))
            printf("Dir ");
        else

            printf("File");

        // display the name of the file
        printf("%20s",file->d_name);

        // display the size of the file
        printf("%10d",info.st_size);

        // show the last modified time
        if(!(S_ISDIR(info.st_mode)))
            printf("%30s\n",ctime(&info.st_mtime));
        else puts("\n");

    }




    return(0);
}

the output pic link : https://i.sstatic.net/tORZU.png


Solution

  • the following proposed code:

    1. includes all the needed header files
    2. performs the desired functionality
    3. properly checks for and handles errors
    4. properly sets up the path for the stat() function
    5. note: the code is being run from the /home/richard/documents/forum directory. This shows that the proposed code properly handles cross directory references.
    6. hidden files are kept hidden by ignoring entries that start with '.'

    and now, the proposed code

    #include <stdio.h>
    #include <stdlib.h>
    #include <dirent.h>
    #include <sys/stat.h>
    #include <time.h>
    #include <string.h>
    
    
    
    int main( void )
    {
        DIR *directory;
        struct dirent *file;
        struct stat info;
        int entries = 0 ;
    
        // entering the directory
        directory = opendir("//home//richard" );
        if ( directory == NULL )
        {
            perror("the directory couldn't be accessed or does not exist");
            return(2);
        }
    
    
        printf("No   type         name              size           TimeStamp \n\n");
        while((file = readdir(directory)))
        {
            if( file->d_name[0] == '.' )
            { // then hidden file, so leave hidden
                continue;
            }
    
            entries++;
    
            char buffer[1024];
            strcpy( buffer, "//home//richard//" );
            strcat( buffer, file->d_name );
            if (stat( buffer, &info ) == -1)
            {
                perror( buffer );
                continue;
            }
            // show the number of the entry
            printf("%2d  ",entries);
    
            // determine if file or directory
            if(S_ISDIR(info.st_mode))
                printf("Dir ");
            else
                printf("File");
    
            // display the name of the file
            printf("%20s",file->d_name);
    
            // display the size of the file
            printf("%10ld",info.st_size);
    
            // show the last modified time
            if(!(S_ISDIR(info.st_mode)))
                printf("%30s\n",ctime(&info.st_mtime));
            else puts("\n");
        }
        return(0);
    }
    

    Part of the output from a typical run of the code is:

    No   type         name              size           TimeStamp 
    
     1  Dir                Music      4096
    
     2  Dir             projects      4096
    
     3  Dir         scull-master      4096
    
     4  Dir         slickeditpro      4096
    
     5  Dir                 snap      4096
    
     6  File   clamscanParms.txt       171     Sat May 20 10:06:43 2017
    
     7  Dir              OpenMPI      4096
    
     8  Dir        clamav.0.99.2      4096
    
     9  Dir               Public      4096
    
    10  Dir            Documents      4096
    
    11  Dir              Desktop      4096
    
    12  Dir            Downloads     20480
    
    13  Dir             Pictures      4096
    
    14  Dir            Templates      4096
    
    15  Dir               Videos      4096
    
    16  File        clamscan.log     42952     Tue Feb 18 13:24:58 2020
    

    As you can see, there are still some alignment between column headers and column data discrepancies that need correction. I'm sure you can handle that detail.