2016-04-26 9 views
1

私は〜250k行のテキストファイルを持っています。各行には、複数のスペースで区切られたデータが含まれています。私は、行ごとにデータを解析し、各行から特定のコンポーネントを取り出したいと思っています。C++で大きいテキストファイルを解析する

入力ファイルと出力ファイルを開き、入力ファイルを1行ずつ解析し、適切なトークンに分割し、新しい行を目的の形式で再構築し、すぐに出力ファイルに出力するプログラムを作成しました。

問題は、実行すると、70から92k行を解析した後に停止してしまうことです。ストールでは、プログラムはまだ実行されますが、何も処理されず、端末のカーソルがそこにとどまり、点滅します。愚かなデバッグ(coutを使って)を使って、92521行目で入力行(正しい行)をチェックしましたが、トークンに分解して整形された行を再構築して停止する部分はありません。

以下、関連するコードを添付します。誰かが何が起こっているのか、つまり私のプログラムがいつも停滞しているのか、どのようにしてこの問題を解決できるのかを教えてくれることを楽しみにしています。ご注意いただきありがとうございます!

#include <iostream> 
#include <fstream> 
#include <cstring> 
#include <sstream> 

int main(int argc, char** argv) { 
    std::ifstream inFile; 
    std::ofstream outFile; 
    std::string inDir("/home/marcin/jnp2/proj/data/oceny.txt"); 
    std::string outDir("/home/marcin/jnp2/proj/data/ocenyout.txt"); 
    outFile.open(outDir, std::ios::out | std::ios::app); 
    inFile.open(inDir, std::ios::in); 
    std::string line; 
    int i = 1; 
    while(std::getline(inFile, line, '\n')) { 
    //for(int i = 0; i < 251819; i++) { // 197858 
     //std::string line; 
     //std::getline(inFile, line, '\n'); 
     //std::cout << "OK1" << std::endl; 
     if(i == 92520) { 
      int x; 
      std::cin >> x; 
     } 
     if(!line.empty() && line[0] != '-' && line[0] != 'K' && line[0] != 'S') { 
      //std::cout << line << std::endl; 
      std::istringstream iss(line); 
      std::string code, name, dyd_cycle, term, grade, person, tmp; 
      iss >> code; 
      std::size_t found; 
      do { 
       if(iss >> tmp) { 
        //iss >> tmp; 
        found = tmp.find("20"); 
        if (found == std::string::npos) 
        if(name.empty()) 
         name = tmp; 
        else 
         name = name + " " + tmp; 
        else 
         dyd_cycle = tmp; 
       } else 
        return 42; 
      } while (found == std::string::npos); 
      //std::cout << "OK2" << std::endl; 
      iss >> term; 
      iss >> grade >> person; 
      std::string formattedLine = code + ";" + name + ";" + dyd_cycle + ";" + term + ";" + grade + ";" + person; 
      outFile << formattedLine << std::endl; 
     } 
     //std::cout << "OK3" << std::endl; 
     std::cout << i++ << std::endl; 
    } 
    inFile.close(); 
    outFile.close(); 
    return 0; 
} 

編集:最後の出力は で停止し、 "1000-621MRB; LONG_CODE_THAT_IM_NOT_SUPPOSED_TO_SHOW Metody realizacjiバズdanych; 2004/TL; 3; 2"。

私はそれが50k + 1行などから始まるようにプログラムを(最初の50k行をスキップするようにハードコーディングして)プログラムに語っていたが、問題 - 私は、私が想定していた正確な出力を得ました。一方、私は50k行ごとにファイルを閉じて、それらを開いて、入力ファイルの正しい行にループするように言ったとき、私はまだ同じ問題を抱えています。

Edit2:私はデバッグにコンパイルし、gdbを使用しました。これは、正しく行を取得している重要な行番号の周りにありますが、コード>>に固執しています。私はCLionでデバッガを使用していたので、しばらくしてからタイムアウトしました。

+3

実際のデバッガを使用して侵入し、何が起こっているのか見てみましたか? – pm100

+1

内部ループが非常に疑わしいと思われる。 「20」の出現がない場合はどうなりますか?また、中括弧のない 'if'のようなものはありません。 – pm100

+0

は処理する最後の行の内容をポストします。また、インデントを修正してください。 – xaxxon

答えて

1

coutを使ってデバッグするのは、必ずしも最良の方法ではありません。プログラムのターミナル/全体的な速度が時々遅くなることがあります。アサーションや実際のデバッガ(GDBなど)を使ってプログラムをデバッグすることができます。デバッガはコードをステップバイステップで実行し、フードの中で起こっていることを正確に示します。

+0

提案していただきありがとうございます。私はそれを再度デバッグしようとしましたが、私のコードが永遠のループに入る原因となった入力が間違っていることがわかりました。 –

+0

あなたがそれを理解したことを知ってうれしいです。あなたがまだいない場合は、回答をアップアップすることを確認してください:) –

+0

問題は、多くの人々(あなたのもの)のコメントから回答を集めたことです...私もそうではないので、私もアップアップすることはできません15人の担当者がいます:/私は5人に担当者に回答を与えたいと思います.2人にコード改善の提案をお願いします。 –

0

実際には、日付が間違っていました。「20」のチェックによって、プログラムは永遠のループに入りました。そのコードを潜在的に危険なものとして指摘してくれたpm100とGeorge Sovetovに感謝したいと思います。私は問題を見つけるためにデバッガを使用しました - それを行うことを提案するためにDeveloperとpm100に感謝します。 gudokのおかげで、私は>> tmpが動作しているかどうかをチェックしました。これは私のループが永遠に永遠になることに気付きました。

私はこのコードを修正し、正規表現を使用して、他の形式のエラーを避けるようにします(knivilの提案に従って)。私はまた、std :: endlの代わりに '\ n'を使用します。kchingerが提案した方法です。すべてのコメントのためにみんなありがとう! :)

関連する問題