tags:

views:

1079

answers:

4

Here is some simple code:

DIR* pd = opendir(xxxx);
struct dirent *cur;
while (cur = readdir(pd)) puts(cur->d_name);

What I get is kind of messy: including dot (.), dot-dot (..) and file names that end with ~.

I want to do exactly the same thing as the command ls. How do I fix this, please?

+10  A: 

This is normal. If you do ls -a (which shows all files, ls -A will show all files except for . and ..), you will see the same output.

. is a link referring to the directory it is in: foo/bar/. is the same thing is foo/bar.

.. is a link referring to the parent directory of the directory it is in: foo/bar/.. is the same thing as foo.

Any other files beginning with . are hidden files (by convention, it is not really enforced by anything; this is different from Windows, where there is a real, official hidden attribute). Files ending with ~ are probably backup files created by your text editor (again, this is convention, these really could be anything).

If you don't want to show these types of files, you have to explicitly check for them and ignore them.

Zifre
+1. Just insert the text "if (*cur->d_name != '.') " in front of "puts(...)" to get the default behaviour of ls.
j_random_hacker
@j_random_hacker: if he doesn't want backup files, he would also have to check for the trailing ~.
Zifre
thank all of you! I would like to choose all answers if I could. now, I hava completely understood this matter. thank you, again!
fwoncn
+1  A: 

This behavior is exactly like what ls -a does. If you want filtering then you'll need to do it after the fact.

Ignacio Vazquez-Abrams
+2  A: 

Eliminating hidden files:

DIR* pd = opendir(xxxx);
struct dirent *cur;
while (cur = readdir(pd)) {
    if (cur->d_name[0] != '.') {
        puts(cur->d_name);
    }
}

Eliminating hidden files and files ending in "~":

DIR* pd = opendir(xxxx);
struct dirent *cur;
while (cur = readdir(pd)) {
    if (cur->d_name[0] != '.' && cur->d_name[strlen(cur->d_name)-1] != '~') {
        puts(cur->d_name);
    }
}
Ankit
j_random_hacker
No, OP wants to filter out files that start with "." OR end in "~".
Ankit
Look at your logic carefully: it will *include* a file with name ".foo" because the 2nd half of the "||" is true (".foo" *doesn't* end with "~"); likewise, a file with name "bar~" will be *included* because the 1st half is true. The only filenames excluded by your 2nd snippet will be those that begin with "." AND end with "~".
j_random_hacker
You're right, my mistake.
Ankit
+1  A: 

Stick a if (cur->d_name[0] != '.') before you process the name.

The UNIX hidden file standard is the leading dot, which . and .. also match.

The trailing ~ is the standard for backup files. It's a little more work to ignore those, but a multi-gigahertz CPU can manage it. Use something like if (cur->d_name[strlen(cur->d_name)-1] == '~')

Zan Lynx