Quote Originally Posted by Gizmo View Post
Nice function, very useful. Therefore I think there is a mistake on the indexes and for my part I would add a test if there is no number.
There's a slight error in the code I posted. If for example the number to compare is not at the end of the string, before ".jpg" but at the beginning followed by a underscore ("_"). The function will return a wrong and unstable value. Why? Because "." is before numbers and "_" after numbers in the ASCII table. As long as I am doing the native comparison for two numbers with a different length, a bug should pop up. Example with "1_..." & "12_..." sometimes it will return true sometimes false. But it should return the smallest which is always "1" (1 < 12).
Qt Code:
  1. bool SailSlideShowWidget::compareNames(const QString& s1,const QString& s2)
  2. {
  3. // ignore common prefix..
  4. int i = 0;
  5. while ((i < s1.length()) && (i < s2.length()) && (s1.at(i).toLower() == s2.at(i).toLower()))
  6. ++i;
  7. ++i;
  8. // something left to compare?
  9. if ((i < s1.length()) && (i < s2.length()))
  10. {
  11. // get number prefix from position i - doesnt matter from which string
  12. int k = i-1;
  13. //If not number return native comparator
  14. if(!s1.at(k).isNumber() || !s2.at(k).isNumber())
  15. {
  16. //Two next lines
  17. //E.g. 1_... < 12_...
  18. if(s1.at(k).isNumber())
  19. return false;
  20. if(s2.at(k).isNumber())
  21. return true;
  22. return QString::compare(s1, s2, Qt::CaseSensitive) < 0;
  23. }
  24. QString n = "";
  25. k--;
  26. while ((k >= 0) && (s1.at(k).isNumber()))
  27. {
  28. n = s1.at(k)+n;
  29. --k;
  30. }
  31. // get relevant/signficant number string for s1
  32. k = i-1;
  33. QString n1 = "";
  34. while ((k < s1.length()) && (s1.at(k).isNumber()))
  35. {
  36. n1 += s1.at(k);
  37. ++k;
  38. }
  39.  
  40. // get relevant/signficant number string for s2
  41. //Decrease by
  42. k = i-1;
  43. QString n2 = "";
  44. while ((k < s2.length()) && (s2.at(k).isNumber()))
  45. {
  46. n2 += s2.at(k);
  47. ++k;
  48. }
  49.  
  50. // got two numbers to compare?
  51. if (!n1.isEmpty() && !n2.isEmpty())
  52. return (n+n1).toInt() < (n+n2).toInt();
  53. else
  54. {
  55. // not a number has to win over a number.. number could have ended earlier... same prefix..
  56. if (!n1.isEmpty())
  57. return false;
  58. if (!n2.isEmpty())
  59. return true;
  60. return s1.at(i) < s2.at(i);
  61. }
  62. }
  63. else
  64. {
  65. // shortest string wins
  66. return s1.length() < s2.length();
  67. }
  68. }
To copy to clipboard, switch view to plain text mode 

I hope this is correct and at least now I get a decent result with all strings.

Giz