Oracle FAQ Your Portal to the Oracle Knowledge Grid
HOME | ASK QUESTION | ADD INFO | SEARCH | E-MAIL US
 

Home -> Community -> Usenet -> c.d.o.misc -> Re: How to get each file name from a Unix dir in filename (not I-node) order.

Re: How to get each file name from a Unix dir in filename (not I-node) order.

From: Eric Laroche <laroche_at_access.ch>
Date: 1998/09/18
Message-ID: <3602D04A.68E@access.ch>#1/1

Alister Miller wrote:
>I have a program (Pro*C) that loops through each file in a directory,
>but I want it get each file in filename order.
>
>I find that the program below does it in i-node order (due to the way
>"readdir" works), which is usually but not always the same as filename
>order.

A few remarks:

>
>Can anyone help me?

You need to sort the data yourself (see [1]). Using opendir()/readdir()/closedir() I suggest:

- read the directory to determine the number of entries
- allocate buffers, read the directory entries
- qsort them

>
>-------------------------------------------------------
>main

probably: 'int main(void)'

>{
> char *sDirName[100];

That's an array of 100 char pointers, not a buffer of 100 chars.

Anyway, why use a hardcoded number for the buffer? Also, in this sample it's not even necessary to copy the directory name, 'char const* sDirName = "/u04/users/fe/CASES_load"' would suffice.

> DIR *dp;
> struct dirent *direntp;
> char *sFileName[257];
>
> strcpy(sDirName, "/u04/users/fe/CASES_load");
>
> if ((dp = opendir(sDirName)) == NULL)
> { exit(EXIT_FAILURE); }

It's a good habit to issue something like 'perror(sDirName)', to indicate what went wrong on which directory.

>
> while ((direntp = readdir(dp)) != NULL)
> {
> /* Get file name */
> sprintf((char *) sFileName, "%s", direntp->d_name);

This is an excellent sample of misusing a cast. ;-)

Clearly, sFileName is the wrong type for using as a sprintf() buffer, again an array of pointers, not a buffer chars. However, since sizeof(char*) is (of course) not smaller than sizeof(char), there's reserved enough space on the stack and the error will typically be uncovered.

> }
>
> closedir(dp);

missing main() return value

>}

--Eric

[1] Sample implementation only considering ASCII character order:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h> /* Posix dirent.h */

static int cmp(void const* a, void const* b) {

    return strcmp(*(char**)a, *(char**)b); }

int main(void)
{

    char const* directory = ".";
    DIR* d;
    struct dirent* e;
    int n, i;
    char** p;

    if ( (d = opendir(directory)) == NULL )     {

        perror(directory);
        return EXIT_FAILURE;

    }
    n = 0;
    while ( (e = readdir(d)) != NULL )

        n++;
    if ( (p = malloc(n * sizeof(*p))) == NULL )

        return EXIT_FAILURE; /* not being very verbose here... */

    rewinddir(d);
    for ( i = 0; i < n && (e = readdir(d)) != NULL; i++ )     {

        if ( (p[i] = malloc(strlen(e->d_name) + 1)) == NULL )
            return EXIT_FAILURE;
        strcpy(p[i], e->d_name);

    }
    n = i; /* in case the directory got shortened in the meantime */     closedir(d);

    qsort(p, n, sizeof(*p), cmp); /* ASCII sort, not alphabetic... */     for ( i = 0; i < n; i++ )

        printf("%s\n", p[i]);

    for ( i = n - 1; i >= 0; i-- )

        free(p[i]);
    free(p);
    return EXIT_SUCCESS;
}



Eric Laroche -- laroche_at_access.ch Received on Fri Sep 18 1998 - 00:00:00 CDT

Original text of this message

HOME | ASK QUESTION | ADD INFO | SEARCH | E-MAIL US