Reputation: 145
I have a text file to sort, which contains the paths to the image files:
/images/calibrationImageRightCamera4.jpg
/images/calibrationImageLeftCamera1.jpg
/images/calibrationImageRightCamera5.jpg
/images/calibrationImageLeftCamera2.jpg
/images/calibrationImageLeftCamera4.jpg
/images/calibrationImageRightCamera6.jpg
/images/calibrationImageLeftCamera3.jpg
/images/calibrationImageRightCamera3.jpg
/images/calibrationImageRightCamera2.jpg
/images/calibrationImageLeftCamera5.jpg
/images/calibrationImageRightCamera1.jpg
/images/calibrationImageLeftCamera7.jpg
/images/calibrationImageLeftCamera6.jpg
/images/calibrationImageRightCamera7.jpg
I use this code to sort the file:
QFile imageListFile;
QStringList sortedImageListFile;
QString filePath;
filePath= "C:/Users/Desktop/textstream/sorted.xml";
imageListFile.setFileName(filePath);
if (!imageListFile.open(QFile::ReadOnly))
{
cout<<"Error opening file"<<endl;
}
else
{
while(!imageListFile.atEnd())
{
sortedImageListFile.append(imageListFile.readLine());
}
imageListFile.close();
}
// Sort the image file
qSort(sortedImageListFile.begin(), sortedImageListFile.end(), naturalSortCallback);
QTextStream stream(&imageListFile);
// Save sorted image in the same file
if(imageListFile.open((QIODevice::ReadWrite | QIODevice::Truncate)))
{
for(QStringList::Iterator it= sortedImageListFile.begin(); it!= sortedImageListFile.end(); ++it)
{
stream << *it;
}
}
imageListFile.close();
inline int findNumberPart(const QString &sIn)
{
QString s= "";
int i= 0;
bool isNum= false;
while(i< sIn.length())
{
if(isNum)
{
if(!sIn[i].isNumber())
break;
s += sIn[i];
}
else
{
if(sIn[i].isNumber())
s += sIn[i];
}
++i;
}
if(s == "")
return 0;
return s.toInt();
}
static bool naturalSortCallback(const QString &s1, const QString &s2)
{
int idx1= findNumberPart(s1);
int idx2= findNumberPart(s2);
return(idx1 < idx2);
}
And I get as result:
/cameraCalibrationFiles/calibrationImageLeftCamera1.jpg
/cameraCalibrationFiles/calibrationImageRightCamera1.jpg
/cameraCalibrationFiles/calibrationImageLeftCamera2.jpg
/cameraCalibrationFiles/calibrationImageRightCamera2.jpg
/cameraCalibrationFiles/calibrationImageLeftCamera3.jpg
/cameraCalibrationFiles/calibrationImageRightCamera3.jpg
/cameraCalibrationFiles/calibrationImageRightCamera4.jpg
/cameraCalibrationFiles/calibrationImageLeftCamera4.jpg
/cameraCalibrationFiles/calibrationImageLeftCamera5.jpg
/cameraCalibrationFiles/calibrationImageRightCamera5.jpg
/cameraCalibrationFiles/calibrationImageRightCamera6.jpg
/cameraCalibrationFiles/calibrationImageLeftCamera6.jpg
/cameraCalibrationFiles/calibrationImageLeftCamera7.jpg
/cameraCalibrationFiles/calibrationImageRightCamera7.jpg
The numbers at the and are sorted correctly but not the filenames. sometimes the words "Left" and "Right" are mixed. The order should look like:
..LeftCamera1.jpg
..RightCamera1.jpg
..LeftCamera2.jpg
..RightCamera2.jpg
.
.
.
Where is my mistake? Thank you for any help.
Upvotes: 3
Views: 986
Reputation: 1255
You should compare number part and then string part on equal number part.
inline int findStringPart(const QString &s)
{
...
return stringPart; //Left or Right
}
static bool naturalSortCallback(const QString &s1, const QString &s2)
{
int numberPart1 = findNumberPart(s1);
int numberPart2 = findNumberPart(s2);
QString stringPart1 = findStringPart(s1);
QString stringPart2 = findStringPart(s2);
if(numberPart1 == numberPart2)
return stringPart1 < stringPart2; //"Left" < "Right"
return numberPart1 < numberPart2;
}
Upvotes: 2
Reputation: 180720
You problem is the way you are comparing the strings.
inline int findNumberPart(const QString &sIn)
Is just giving you the ending number from the string. So any string ending in 1
will come before any other string. This is why the right and left cameras file names are getting mixed together and in no particular order. What you need to do is compare the number part and if that is equal then compare the string part. If not then just compare the number part.
Upvotes: 3