Algorithm Alley
by David Wincelberg


Listing One
// SNSimpleLib.h -- Alphanumeric Ordering
#ifndef SNSIMPLELIB_H
#define SNSIMPLELIB_H

#ifdef __cplusplus
extern "C" {
#endif

int  SimpleANCompare (const char *pszName1, const char *pszName2);
void SetSNSLocaleSort (int bLocaleSort);
#ifdef __cplusplus
}
#endif
#endif  // SNSIMPLELIB_H


Listing Two
// SNSimpleLib.c -- Alphanumeric Ordering
#include <ctype.h>      // for isdigit, tolower
#include <stdlib.h>     // for atoi
#include <string.h>     // for _strnicoll (Windows)
#include "SNSimpleLib.h"

static int g_bLocaleSort = 1;
// Action:  Simple alphanumeric comparisons.
// Notes:   Works when there is a digit in the same starting place in
//    each filename. Limited to numbers smaller than 2^31, around 2 billion.
int SimpleANCompare (const char *pszName1, const char *pszName2) {
    register const char *pszN1 = pszName1, *pszN2 = pszName2;
    int nTest;
    while (*pszN1 != '\0' && *pszN2 != '\0') {
        if (isdigit (*pszN1) && isdigit (*pszN2)) {
            if ((nTest = atoi (pszN1) - atoi (pszN2)))
                return nTest;
            // Moves past the numbers
            while (isdigit (*pszN1)) pszN1++;
            while (isdigit (*pszN2)) pszN2++;
        }
        else {
            if (g_bLocaleSort)    // locale caseless match
                nTest = _strnicoll (pszN1, pszN2, 1);           
            else                  // caseless match
                nTest = tolower (*pszN1) - tolower (*pszN2);
            if (nTest)
                return nTest;
            else {
                pszN1++;  pszN2++;
            }
        }
    }
    return (*pszN1 - *pszN2);   // one string has ended
}   // SimpleANCompare
// Action:  Turns locale sorting on or off.
// Note:    This functionality may need to be removed for non-Windows OSes.
void SetSNSLocaleSort (int bLocaleSort) {
    g_bLocaleSort = bLocaleSort;
}


2

