0

I'm using the scandir() function for one of my C programs. Within scandir(), I ask it to alphasort my directory. Yet, when I have files such as: alpha,bob, they're placed under files like DARK or Decomp.txt. I assume this is because of how the ascii values work. But is there are way so that my ordering would be: alpha,bob,DARK,decomp.txt rather than DARK,Decomp.txt,alpha,bob.

Because essentially I am supposed to model the tree unix command and need it to be sorted in such a manner.

My code below only shows how i'm printing.

void listdir(const char *name, int level, int hidden, int access)
{
DIR *dir;
struct dirent **entry;
int n = 2;
int num;
char path[1024];
int len;
int count = 0;
if (!(dir = opendir(name)))
{
    printf("%s [error opening dir]\n", name);
    return;
}
num = scandir(name,&entry,NULL,alphasort);
if(num<0)
{
    perror("scandir");
}
while(n<num){
    /* Bunch of formatting to print files/directory */
    /* Pseudocode */
    /* if( it is a directory)
       print current directory
       recursive call on function

       else
       print current file */
    n++;
}

closedir(dir);

}

GreenSkies
  • 141
  • 1
  • 10

1 Answers1

1

Something like:

#include <strings.h>

int alphasort_case_insensitive(const struct dirent ** a, const struct dirent **b) {
  return(strcasecmp((*(const struct dirent **)dirent1)->d_name,
                    (*(const struct dirent **)dirent2)->d_name));
}
Gene
  • 46,253
  • 4
  • 58
  • 96
  • The stricmp() is non-standard. The posix name is `strcasecmp()`, but you'll need to `#include ` – wildplasser Feb 23 '17 at 00:50
  • Thanks. Adjusted! – Gene Feb 24 '17 at 03:14
  • I'm curious about your claim about null bytes/characters. There isn't room in the rest of POSIX for nulls embedded in file names, and I'm more than a little surprised to hear that [`readdir()`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/readdir.html) — or the [``](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/dirent.h.html) specification — allows for embedded nulls. Can you explain how/where it does so? – Jonathan Leffler Feb 24 '17 at 03:25
  • @JonathanLeffler I could easily be wrong. I noted at least one `dirent` header def that included optional fields for name length. I concluded this might be to allow embedded nulls. – Gene Feb 24 '17 at 18:02
  • Filenames on Unix can't contain two characters: slash and null. The slash is reserved as the path separator; null as the end marker. (See: [What characters are forbidden in Windows and Linux directory names?](http://stackoverflow.com/questions/1976007/)) The provision of `d_namlen` or similar is non-standard (POSIX only mandates `d_name` in `struct dirent`) but convenient; it saves calling `strlen()`. But that's all; it doesn't allow nulls in the names. Nothing in Unix allows nulls in file names. – Jonathan Leffler Feb 24 '17 at 18:22