Sorting an array of characters is an often requested item on arduino.cc, but examples are lacking.
So here is an example; If this is helpful, please say Thx below.
Arduino has a max of 2K of RAM. It's not a lot. Your libraries will use a lot of it.
It doesn't leave much when dealing with char arrays.
Using malloc is the most efficient method of using RAM. The number of bytes that you need is worked out and
assigned at run-time.
Remember to also Free the malloc'd RAM when you've finished with it !
// In this example, we will use fileNames as the strings to sort.
// the fileNames have an 8.3 format, so the max length is 13 chars (include the \0 terminator)
//
// Arrays : the first element is the 0'th element.
//
#define MaxInArray 20
char *fileName[MaxInArray]; // Pointers to character strings, address of each
// is to be determined by malloc.
// And declare a string, which contains the max number of chars that you desire. (Sensibly !)
char tempString[13]; //Allocate 50 bytes as a regular character array.
byte numberElementsInArray;
byte i;
void setup()
{
Serial.begin(9600);
numberElementsInArray = 0;
Serial.println("Populating the array with some randomly chosen 'filenames'.");
populateFileArray();
printArray();
Serial.println("Sorting this array :");
sortFileArray();
printArray();
}
void loop()
{
// No loop; all the processing has been done already.
}
void printArray()
{
Serial.println("The array currently holds :");
for (i = 0; i< numberElementsInArray; i++)
{
Serial.println(fileName[i]);
}
}
// -----------------------------------------------------------------------------------------------
// switchArray - This function takes the element in the array that we are dealing with, and
// switches the pointers between this one and the previous one.
// -----------------------------------------------------------------------------------------------
void switchArray(byte value)
{
// switch pointers i and i-1, using a temp pointer.
char *tempPointer;
tempPointer = fileName[value-1];
fileName[value-1] = fileName[value];
fileName[value] = tempPointer;
}
// -------------------------------------------------------------------------
// This is a real neat function. It decides whether the first string is "less than"
// or "greater than" the previous string in the array. Input 2 pointers to chars;
// if the function returns 1 then you should switch the pointers.
// -------------------------------------------------------------------------
//
// Check 2 character arrays; return FALSE if #2 > 1;
// return TRUE if #2 > #1 for the switch. Return 1 = TRUE, 0 = FALSE
byte arrayLessThan(char *ptr_1, char *ptr_2)
{
char check1;
char check2;
int i = 0;
while (i < strlen(ptr_1)) // For each character in string 1, starting with the first:
{
check1 = (char)ptr_1[i]; // get the same char from string 1 and string 2
//Serial.print("Check 1 is "); Serial.print(check1);
if (strlen(ptr_2) < i) // If string 2 is shorter, then switch them
{
return 1;
}
else
{
check2 = (char)ptr_2[i];
// Serial.print("Check 2 is "); Serial.println(check2);
if (check2 > check1)
{
return 1; // String 2 is greater; so switch them
}
if (check2 < check1)
{
return 0; // String 2 is LESS; so DONT switch them
}
// OTHERWISE they're equal so far; check the next char !!
i++;
}
}
return 0;
}
// -----------------------------------------------------------------------
// This is the guts of the sort function. It's also neat.
// It compares the current element with each previous element, and switches
// it to it's final place.
// -----------------------------------------------------------------------
void sortFileArray()
{
int innerLoop ;
int mainLoop ;
for ( mainLoop = 1; mainLoop < numberElementsInArray; mainLoop++)
{
innerLoop = mainLoop;
while (innerLoop >= 1)
{
if (arrayLessThan(fileName[innerLoop], fileName[innerLoop-1]) == 1)
{
// Serial.print("Switching ");
// Serial.print(fileName[innerLoop]);
// Serial.print(" and ");
// Serial.println(fileName[innerLoop-1]);
switchArray(innerLoop);
}
innerLoop--;
}
}
}
// -----------------------------------------------------------------------
// You remember we have to free the malloc's ? Well, it's a simple function.
// The pointer points to nothing, and the memory that was used is
// -----------------------------------------------------------------------
void freeMessageMemory()
{
// If we have previous messages, then free the memory
for (byte i=1; i<=numberElementsInArray; i++)
{
free(fileName[i-1]);
}
numberElementsInArray = 0;
}
// ---------------------------------------------------------------------------
// This is the part you care least about; how to populate the char array in the first place.
// I have taken from this code from an MP3 project where I read the fies in a directory into
// that array of pointers.
// ---------------------------------------------------------------------------
//
void populateFileArray()
{
freeMessageMemory(); // Start by freeing previously allocated malloc pointers
numberElementsInArray = 0;
//
// For this demo, we will create some hardcoded strings
//
sprintf(tempString, "%s", "myfile.dat");
numberElementsInArray++;
fileName[numberElementsInArray-1] = (char *)malloc(13);
//checkMemory();
sprintf(fileName[numberElementsInArray-1],"%s", tempString);
sprintf(tempString, "%s", "FILE2_01.MP3");
numberElementsInArray++;
fileName[numberElementsInArray-1] = (char *)malloc(13);
//checkMemory();
sprintf(fileName[numberElementsInArray-1],"%s", tempString);
sprintf(tempString, "%s", "LETTER.DOC");
numberElementsInArray++;
fileName[numberElementsInArray-1] = (char *)malloc(13);
//checkMemory();
sprintf(fileName[numberElementsInArray-1],"%s", tempString);
sprintf(tempString, "%s", "FILE1_01.MP3");
numberElementsInArray++;
fileName[numberElementsInArray-1] = (char *)malloc(13);
//checkMemory();
sprintf(fileName[numberElementsInArray-1],"%s", tempString);
}
|