Oracle FAQ | Your Portal to the Oracle Knowledge Grid |
![]() |
![]() |
Home -> Community -> Usenet -> c.d.o.misc -> Re: How to get each file name from a Unix dir in filename (not I-node) order.
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++;
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);
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;
}
![]() |
![]() |