Problem with displaying file sizes.

Started by
6 comments, last by LordG 21 years, 10 months ago
Ok, I wrote a C program which reads a directory and prints out all the files within that directory. The printout includes the file name and the file size. The problem I have is printing out the file size. It seems to work perfectly if I choose to read a directory, which this program is located in. But if I choose to read another directory, for example, a subdirectory or a directory above the directory where my program is located, it doesn't seem to print out the file size correcty. Can someone help me out. Here's what I have so far.
      
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <sys/stat.h>
#include <errno.h>

main(int argc, char *argv[])
{
    DIR *dirp;
    struct dirent *direntp;
    struct stat statbuf;

    /* Invalid usage. */
    if (argc != 2) {
       fprintf(stderr,"Usage: %s directory_name\n", argv[0]);
       exit(1);
    }
    /* Given argument is not a directory. */
    if ((dirp = opendir(argv[1])) == NULL) {
       fprintf(stderr, "Could not open %s directory: %s\n",
               argv[1], strerror(errno));
       exit(1);
    }
    /* Print a list of files with its name and size. */
    while ( (direntp = readdir( dirp )) != NULL ) {
       stat(direntp->d_name, &statbuf);
       printf("%s  %i\n", direntp->d_name, statbuf.st_size);
    }
    
    closedir(dirp);
    exit(0);
}
      
[edited by - lordg on May 31, 2002 6:37:37 PM] [edited by - lordg on May 31, 2002 6:39:45 PM]
Advertisement
You''re forgetting that stat is looking in the current directory (and the PATH directories) only. You need to create a string that is basically argv[1]/direntp->d_name, and pass that to stat. Or, you could chdir into argv[1], and then do the stat loop.

Huh? I don''t quite understand. This is my first time doing this directoy programming stuff, so there''s a lot of stuff I don''t know.

So I shouldn''t pass dirent->d_name to stat, but create a string to store arg[1] and pass that to stat?
Here''s a version with the simpler of the two fixes I suggested:

  #include <stdio.h>#include <stdlib.h>#include <string.h>#include <dirent.h>#include <sys/stat.h>#include <errno.h>int main(int argc, char *argv[]) {    DIR *dirp;    struct dirent *direntp;    struct stat statbuf;    if(argc != 2) {       fprintf(stderr,"Usage: %s directory_name\n", argv[0]);       return -1;    }    if((dirp = opendir(argv[1])) == NULL) {       fprintf(stderr, "Could not open %s directory: %s\n", argv[1], strerror(errno));       return -1;    }	chdir(argv[1]);    while((direntp = readdir( dirp )) != NULL) {       stat(direntp->d_name, &statbuf);       printf("%s  %i\n", direntp->d_name, statbuf.st_size);    }        closedir(dirp);    return 0;}  


BTW: While I didn''t need to resort to this but, you could have found the error by checking the return value of stat, and printing a strerror(errno) out if it wasn''t 0.
Can you tell me what does the function chdir() does?

I''m assuming it changes directory... can you explain it to me please.
quote:Original post by LordG
Can you tell me what does the function chdir() does? I''m assuming it changes directory...

That''s what it does. Here''s an example to explain this. Say the following is your filesystem:
/
/mydirlist
/filea
/dir/
/dir/fileb
If we''re currently in root (/) and we run your program with "./mydirlist ." we get the list:
. 4096 (all directories will have this size)
.. 4096
dir 4096
filea x-bytes

If we run your program with "./mydirlist dir" we get the list:
. 4096
.. 4096
fileb 4096

Why did dir/fileb give us 4096? Because there was an error finding "/fileb" and the stat struct wasn''t messed with. Why was there an error? Because "/fileb" doesn''t exist. "fileb" becomes "/fileb" because we''re in the root directory. So, with the fix I suggest, if we did "./mydirlist dir" we''d get moved into dir before the file size testing begins. So, when we try to find "fileb" the actual path we''re looking for is "/dir/fileb", which _does_ exist, so we get the correct size back from stat.

I see, thanks alot man.

This topic is closed to new replies.

Advertisement