Wednesday 17 October 2012

C Program to sort filenames in a directory?

How do you sort filenames in a directory?


The below example shows how to get a list of files one at a time. The example uses the _dos_findfirst() and _dos_findnext() functions to walk through the directory structure. As each filename is found, it is printed to the screen.

When you are sorting the filenames in a directory, the one-at- a-time approach does not work. You need some way to store the filenames and then sort them when all filenames have been obtained. This task can be accomplished by creating an array of pointers to find_t structures for each filename that is found. As each filename is found in the directory, memory is allocated to hold the find_t entry for that file. When all filenames have been found, the qsort() function is used to sort the array of find_t structures by filename.

The qsort() function can be found in your compiler’s library. This function takes four parameters: a pointer to the array you are sorting, the number of elements to sort, the size of each element, and a pointer to a function that compares two elements of the array you are sorting. The comparison function is a user-defined function that you supply. It returns a value less than zero if the first element is less than the second element, greater than zero if the first element is greater than the second element, or zero if the two elements are equal. Consider the following example:

#include <stdio.h>
#include <direct.h>
#include <dos.h>
#include <malloc.h>
#include <memory.h>
#include <string.h>

typedef struct find_t FILE_BLOCK;

int sort_files(FILE_BLOCK**, FILE_BLOCK**);
void main(void);

void main(void)
{

FILE_BLOCK f_block;         /* Define the find_t structure variable */
int ret_code;                           /* Define a variable to store the return codes */
FILE_BLOCK** file_list;      /* Used to sort the files */
int file_count;                          /* Used to count the files */
int x;                                         /* Counter variable */


file_count = -1;


/* Allocate room to hold up to 512 directory entries. */
file_list = (FILE_BLOCK**) malloc(sizeof(FILE_BLOCK*) * 512);


printf(“\nDirectory listing of all files in this directory:\n\n”);


/* Use the “*.*” file mask and the 0xFF attribute mask to list all files in the directory, including system files, hidden files, and subdirectory names. */


ret_code = _dos_findfirst(“*.*”, 0xFF, &f_block);


/* The _dos_findfirst() function returns a 0 when it is successful and has found a valid filename in the directory. */


while (ret_code == 0 && file_count < 512)
{


/* Add this filename to the file list */


file_list[++file_count] = (FILE_BLOCK*)  malloc(sizeof(FILE_BLOCK));


*file_list[file_count] = f_block;


/* Use the _dos_findnext() function to look for the next file in the directory. */


ret_code = _dos_findnext(&f_block);


}


/* Sort the files */


qsort(file_list, file_count, sizeof(FILE_BLOCK*), sort_files);


/* Now, iterate through the sorted array of filenames and print each entry. */


for (x=0; x<file_count; x++)
{


printf(“%-12s\n”, file_list[x]->name);


}


printf(“\nEnd of directory listing.\n”);


}

int sort_files(FILE_BLOCK** a, FILE_BLOCK** b)
{

return (strcmp((*a)->name, (*b)->name));


}

This example uses the user-defined function named sort_files() to compare two filenames and return the appropriate value based on the return value from the standard C library function strcmp(). Using this same technique, you can easily modify the program to sort by date, time, extension, or size by changing the element on which the sort_files() function operates.

No comments:

Post a Comment