Alphabetical String Sorting

Hello again,
I've been searching for a way to sort strings alphabetically from a to z or from z to a, and the most frequent solution I find from google is to put a string array into a <vector> vector container and use <algorithm> sort(). The other solutions I find I am having trouble understanding and getting them to work. Heres a snippet of the code using vector/sort() which is malfunctioning:
1
2
3
4
5
6
7
8
9
vector<string> wordListVector (stringArray, stringArray+wordElementCount);
vector<string>::iterator it2;

sort (wordListVector.begin(), wordListVector.end(), less<string>());

// Print out content.
cout << "wordListVector contains: \n\n";
for (it2 = wordListVector.begin(); it2 != wordListVector.end(); it2++)
  cout << '\n' << *it2;

sort() arranges the output in random order if I do this. Does this have something to do with the coding of ASCII? I've never read anything concerning that; though I am reading a lot about putting my strings into different STL containers and/or using one of the few STL versions of sort().

If anyone can explain to me how string sorting is done using a vector/sort() method or is willing to explain some other STL based method, I would be most grateful for the help. I have searched the reference documents and forums on this site as well, and am having no success.

My only solution to this problem otherwise is to develop my own approach by using a string iterator to find all the strings starting with 'a', and then 'b', etc. and then swapping them around. I wouldn't mind doing that, but I'm quite sure that any STL approach is probably more efficient than what I could come up with, given my limited experience.
Last edited on
if you use
 
sort( wordListVector.begin(), wordListVector.end() );

strings will be sorted in ascending order. If you want to sort list descending order, you need to send a comparator as a parameter.
 
sort( wordListVector.begin(), wordListVector.end() , compareString ); 


Or you can use STL list class. STL list has own sort function .
1
2
3
4
list<string> sList ;
...
...
sList.sort();


Okay I implemented the <list> method and got it to run. And then I realized that I was getting the same output as before. Seemingly random output. but it wasn't random at all, really, it was just ordering all the capital letters before the lower case ones. :P But by looking at the <list> example in the reference section I was able to get both methods to give the desired output:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Comparison; not case sensitive.
bool compareNoCase (string first, string second)
{
  ULONG i=0;
  while ((i < first.length()) && (i < second.length()))
  {
    if (tolower (first[i]) < tolower (second[i])) return true;
    else if (tolower (first[i]) > tolower (second[i])) return false;
    i++;
  }

  if (first.length() < second.length()) return true;
  else return false;
}

Using <list> method:
1
2
3
4
5
6
7
8
9
10
11
12
list <string> wordList_List; 
list <string>::iterator it2;

for (ULONG i = 0; i != wordElementCount; i++)
   wordList_List.push_back (stringArray[i]);

wordList_List.sort (compareNoCase);
	
// Print out content.
cout << "wordList_List contains: \n";
for (it2 = wordList_List.begin(); it2 != wordList_List.end(); it2++)
	cout << '\n' << *it2;

Using vector/ sort() :
1
2
3
4
5
6
7
8
9
vector<string> wordListVector (stringArray, stringArray+wordElementCount);
vector<string>::iterator it2;

sort (wordListVector.begin(), wordListVector.end(), compareNoCase);

// Print out content.
cout << "wordListVector contains: \n";
for (it2 = wordListVector.begin(); it2 != wordListVector.end(); it2++)
	cout << '\n' << *it2

Well, you led me to the answer Dufresne, thanks for you help. I'm not sure what a comparator string is though.
Last edited on
You could use strcasecmp.

1
2
3
bool compareNoCase( const string& s1, const string& s2 ) {
    return strcasecmp( s1.c_str(), s2.c_str() ) <= 0;
}


string comparator in this case is just referring to a function that compares strings.
compareNoCase is one. less<string> is another.
I see, thank you for clearing that up jsmith.

EDIT:
 
error C3861: 'strcasecmp': identifier not found


While trying jsmith's version or compareNoCose() which includes strcasecmp(), the compiler turns into a complainer with the above error. I'm including the <string> header of course, and I even tried also using <cstring.h> thinking it might be a c version function, because it uses s1.c_str() to convert the string into a char array, correct? But no success. I'm not sure whats going on though.
Last edited on
#include <string.h> (or #include <strings.h>, strings, with an 's' at the end)

strcasecmp BSD4.4 compatible according to my man page, FWIW.
Okay, I'm not sure exactly what BSD4.4 is but every mention on google has it relating to Unix, which is great, but at the moment I'm needing to work with Windows as with Linux I'm not able to find the correct versions of my hardware drivers on those operating systems.

In any case I'm using Visual Studio C++ 2008 Express and it doesn't come with a version of string.h or strings.h, but thanks for the suggestion which might come in handy when I'm able to finially make the move over to Linux (Kubuntu) which is a far better operating system compared to Windows, except for the driver thing.
Last edited on
Ah, in that case I apologize for derailing you on the tangent.
That's no problem, thanks for trying to help.
Topic archived. No new replies allowed.