2016-09-10 4 views
0

Я работаю над программой для создания списка из большого QStringList. Таким образом, в основном после совпадения строк цикл while начинает добавлять следующие строки в список. Эта часть работает нормально. Единственная проблема, я имею в виду, что программа неожиданно завершает работу, потому что я не знаю, как я должен добавить механизм EOF.Продолжить цикл while до EOF (Qt)

Обновление с более детальным кодом

К сожалению, не обеспечивающих достаточно подробные сведения о моем коде. Вот как выглядит мой код сейчас. Поэтому после первого появления строки «ТИП ПАКЕТА» я использую функцию storeLines() для хранения следующих строк в одном из трех зависимых списков. И это будет продолжаться до следующего совпадения «ТИП ПАКЕТА» или EOF. Единственное, что сейчас неправильно работает, - это когда итератор находится в последней строке QStringList. Это как-то не обнаруживает, что следующий является inputline.end()

void storeLines(QString department, QStringList::iterator current_line, QStringList::iterator endline){ 
while(QString::compare(*(current_line + 1),"PACKAGE TYPE") && (++current_line != endline)){ //this is not working 
    if(!QString::compare(department, "MDA")) mda_list.push_back(*current_line); 
    else if(!QString::compare(department, "SDA")) sda_list.push_back(*current_line); 
    else mix_list.push_back(*current_line); 
    } 
} 

void void MainWindow::on_pushButton_clicked(){ 
    QString input = ui->listinput->toPlainText().toLatin1(); 
    QStringList inputline = input.split("\n", QString::SkipEmptyParts); 

    for(QStringList::iterator pkg_header(inputline.begin()); pkg_header != inputline.end(); ++pkg_header){ 
     if(!QString::compare(*pkg_header,"PACKAGE TYPE")){ 
      ++pkg_header; 
      if(!QString::compare(*pkg_header,"Department-mda:")) storeLines("MDA", pkg_header, inputline.end()); 
      else if(!QString::compare(*pkg_header,"Department-sda:")) storeLines("SDA", pkg_header, inputline.end()); 
      else storeLines("MIX", pkg_header, inputline.end()); 
     } 
    } 
} 

Заранее спасибо!

+0

Знаете ли вы, как написать условие остановки для цикла 'for', но не для цикла while? Конечно, вы должны использовать ту же проверку в обоих местах. –

+0

@IgorTandetnik Я упростил код. В действительности цикл while в другой выполняется. Я попытался добавить параметр 'inputline.end()' в качестве параметра, но это, похоже, не сработало. – Mrchacha

+0

Ну, вам нужно заставить его работать. Сравнение с конечным итератором * - это * то, как вы обнаруживаете конец диапазона. Ваши попытки сравнить с «NULL» - это нонсенс. –

ответ

0

Ваше намерение состоит в том, чтобы найти строку «ТИП ПАКЕТА» в существующем списке, а затем скопировать остальные элементы в списке в новый список.

Если это так, то почему бы не сделать именно это?

for(QStringList::iterator current_line(inputline.begin()); current_line != inputline.end(); ++current_line){ 
    if(!QString::compare(*current_line,"PACKAGE TYPE"){ 
     list.insert(list.end(), ++current_line, inputline.end()); 
     break; 
    } 
} 
+0

Извините, что вы не поняли проблему. Я обновил код с более подробным описанием. Дело в том, что мне нужно отслеживать EOF и возможный следующий матч «ТИП ПАКЕТА». – Mrchacha

+0

Нет такой вещи под названием «EOF». «EOF» означает «конец файла» при чтении его содержимого.Здесь нет файлов. Вы все еще не можете объяснить, что хотите. –

+0

Итак, я хочу выяснить, как я могу проверить, находится ли 'current_line' в последней строке QStringList. У меня есть QStringList, где есть несколько разделов, каждый раздел начинается со строки «ТИП ПАКЕТА». Следующая строка определяет, к какому отделу принадлежит пакет; это может быть в mda, sda или в отделе смешивания. И затем я хочу сохранить следующие строки в списках отделов до следующего раздела «ТИП ПАКЕТА» или окончания QStringList. – Mrchacha

1

Вы пишете синтаксический анализатор - это часто проще писать, как вы обычно писать один, делая состояния явных и перебор последовательно над каждым элементом входного потока. Таким образом, вы не будете делать никаких ошибок в итераторе по отдельности.

Этот код соответствует намерению вашего вопроса и делает очевидным, что вы пропустили случай: когда вы ожидаете отдел, вы не реагируете на присутствующий PACKAGE TYPE. Вы могли бы сигнализировать об ошибке или оставаться в состоянии DEPARTMENT, но я полагаю, вы должны справиться с этим, а не просто игнорировать его.

QStringList mda_list, sda_list, mix_list; 

void parse(const QString & input) { 
    enum { 
     TYPE, 
     DEPARTMENT, 
     ITEMS 
    } state = TYPE; 
    auto list = &mix_list; 
    auto const kPackageType = QStringLiteral("PACKAGE TYPE"); 

    for (auto const element : input.split("\n", QString::SkipEmptyParts)) { 
     switch (state) { 
     case TYPE: 
      if (element == kPackageType) 
       state = DEPARTMENT; 
      break; 
     case DEPARTMENT: 
      if (element == QStringLiteral("Department-mda:")) 
       list = &mda_list; 
      else if (element == QStringLiteral("Department-sda:")) 
       list = &sda_list; 
      state = ITEMS; 
      break; 
     case ITEMS: 
      if (element == kPackageType) 
       state = DEPARTMENT; 
      else 
       *list << element; 
      break; 
     } 
    } 
} 

Использование QStringLiteral дает время компиляции встроенные строковые экземпляры для сравнения. Код будет работать так же хорошо, если вы удалили обертки QStringLiteral(...) за счет неизбежной преждевременной пессимизации.