Sign in to follow this  

Optimization of showing dir contents function

This topic is 4857 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello, I wrote a code to show the contents of a directory + file size in bytes. Ok, no problem with it. I just want to know if it is possible to write a shorter code to jump the "." and ".." as you can see in my if: /* Jump the actual dir indicator (.) and before dir (..) */. Thanks Alfred
#include<dirent.h>
#include<stdio.h>
#include<sys/stat.h>

const char *actual_dir = "D:/Programacao/Aprendizagem/C - Completo e Total/cap9/";

int main()
{
    DIR *dr;
    struct dirent *datum;
    struct stat buf;
    
    if(!(dr = opendir(actual_dir)))
    {
        printf("Error when trying to open dir...");
        return 0;
    }    
    
    /* Lists directory content including file names started with a dot (.) */
    while(datum = readdir(dr))
    {
        /* Jump the actual dir indicator (.) and before dir (..) */
        if( (*(datum->d_name) == '.' && datum->d_namlen == 1) // .
            ||
            ((*(datum->d_name) == '.' && *(datum->d_name+1) == '.') && datum->d_namlen == 2 ) // ..
        )
        {            
            continue;            
        }        
        
        /* Get file data */
        stat(datum->d_name, &buf);
        
        printf("%-50s%10d\n", datum->d_name, buf.st_size);
    }
    
    printf("\nPress [ENTER] to exit.\n");
    getchar();
    return 0;
}


The struct dirent as you see in "dirent.h":
struct dirent
{
	long		d_ino;		/* Always zero. */
	unsigned short	d_reclen;	/* Always zero. */
	unsigned short	d_namlen;	/* Length of name in d_name. */
	char		d_name[FILENAME_MAX]; /* File name. */
};

Share this post


Link to post
Share on other sites
Well, if you changed to using c-style nul-terminated strings (why are you storing the length seperately? is the string not nul terminated already?), then you could use strcmp

Share this post


Link to post
Share on other sites
Oh! strcmp... I have had forgot it.
Thanks Extrarius! Rate ++ to you.

why are you storing the length seperately?
I'm using the C standart library, it stores.

I just changed the if to:

/* Jump the actual dir indicator (.) and before dir (..) */
if(!strcmp(datum->d_name, ".") || !strcmp(datum->d_name, ".."))
{
continue;
}



and it works perfect as the before sentence.

Share this post


Link to post
Share on other sites
So does that code actually work? Because if it does, then that means that the strings are null-terminated, which makes it alot easier to compare them with other strings.

Share this post


Link to post
Share on other sites
Quote:
Original post by bytecoder
So does that code actually work? Because if it does, then that means that the strings are null-terminated, which makes it alot easier to compare them with other strings.


Yes, both codes worked well.

Share this post


Link to post
Share on other sites
BTW, unless you're "optimizing" for source code length, the strcmp version might be worse for you because it is actually larger in terms of (machine)code size. But it does look prettier.

Share this post


Link to post
Share on other sites
Quote:

BTW, unless you're "optimizing" for source code length, the strcmp version might be worse for you because it is actually larger in terms of (machine)code size. But it does look prettier.

Not just prettier, but more readable, too; which is much more important than optimizing for speed considering the fact that you usually read code more often than you write it.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Quote:
Original post by bytecoder
Quote:

BTW, unless you're "optimizing" for source code length, the strcmp version might be worse for you because it is actually larger in terms of (machine)code size. But it does look prettier.

Not just prettier, but more readable, too; which is much more important than optimizing for speed considering the fact that you usually read code more often than you write it.
Well, you usually run code more often than you read it or write it, so speed is pretty important.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster

/* Lists directory content including file names started with a dot (.) */
while(datum = readdir(dr))
if(strcmp( datum->d_name, ".") && strcmp( datum->d_name, ".."))
{
/* Get file data */
stat(datum->d_name, &buf);
printf("%-50s%10d\n", datum->d_name, buf.st_size);
}



cheers!

Share this post


Link to post
Share on other sites
I'd not rely on null-terminated strings... i prefer strings with length.(but it's my personal opinion)
Also i don't like to use any functions i haven't wrote myself,if i can do it without and it also will be faster :-)

on subject, i think it may be better to check for length first,then access the thing (and always do so).

Share this post


Link to post
Share on other sites
Guest Anonymous Poster

while(datum = readdir(dr))
if( *datum->d_name != '.' || datum->d_namlen != 2 || datum->d_name[1] != '.')
{
/* Get file data */
stat(datum->d_name, &buf);
printf("%-50s%10d\n", datum->d_name, buf.st_size);
}


no need for extra coupling short and sweet and quite understandable.

Share this post


Link to post
Share on other sites

This topic is 4857 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this