2016-09-10 6 views
0

大きなQStringListからリストを作成するプログラムを作成しています。したがって、基本的に文字列の一致後、whileループが次の文字列をリストに追加し始めます。この部分は正常に動作しています。私が持つ唯一の問題は、EOFメカニズムをどのように追加すべきか分からないので、プログラムが予期せず終了することです。私のコードについての十分な詳細を提供していないため申し訳ありませんEOF(Qt)までwhileループを続ける

より詳細なコードで更新

。これは私のコードが今見える方法です。最初の文字列「PACKAGE TYPE」が検出された後、関数storeLines()を使用して、次の文字列を3つのリストのいずれかに格納します。そして、これは次の "PACKAGE TYPE"マッチまたは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

あなたの明らかな目的は、既存のリストで文字列 "PACKAGE TYPE"を見つけて、リストの残りの要素を新しいリストにコピーすることです。

これが当てはまる場合は、どうしてそうはしませんか?あなたはパーサを書いている

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の最後の文字列にあるかどうかを調べる方法を理解したいと思います。私はいくつかのセクションがあり、各セクションは文字列 "PACKAGE TYPE"で始まるQStringListを持っています。次の文字列は、パッケージが属する部門を定義します。それはmda、sda、またはmix部にあります。そして、次の "PACKAGE TYPE"セクションまたはQStringListの最後まで、次の文字列を部門リストに格納します。 – Mrchacha

1

- それはあなたが通常の状態が明示的にすることと、入力ストリームのすべての要素の上に順番に繰り返すことで、1を書きたいようにそれを書くために、多くの場合、最も簡単なのです。あなたは、そのようなoff-by-oneイテレーターの誤りを何も起こさないでしょう。

このコードはあなたの質問の意図と一致し、ケースを見逃していることが明らかになります。部門が必要な場合は、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(...)ラッパーを削除した場合、コードはまったく同様に機能しますが、それは避けられない早すぎるペシメーションによるコストです。

関連する問題