qt — естественная сортировка имен файлов с выпуском чисел

У меня есть текстовый файл для сортировки, который содержит пути к файлам изображений:

/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

Я использую этот код для сортировки файла:

    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);
}

И я получаю в результате:

/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

Числа в и отсортированы правильно, но не имена файлов. иногда слова «левый» и «правый» смешиваются. Заказ должен выглядеть так:

..LeftCamera1.jpg
..RightCamera1.jpg
..LeftCamera2.jpg
..RightCamera2.jpg
.
.
.

Где моя ошибка? Спасибо за любую помощь.

3

Решение

Вы должны сравнить числовую часть и затем строковую часть на равную числовую часть.

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;
}
2

Другие решения

Ваша проблема в том, как вы сравниваете строки.

inline int findNumberPart(const QString &sIn)

Просто дает вам конечный номер из строки. Так что любая строка заканчивается 1 будет стоять перед любой другой строкой. Вот почему имена файлов правой и левой камер смешиваются друг с другом и в произвольном порядке. Что вам нужно сделать, это сравнить числовую часть и, если она равна, сравнить строковую часть. Если нет, то просто сравните числовую часть.

3

По вопросам рекламы [email protected]