解析C++中的大文本文件

问题描述:

我有一个〜250k行的文本文件。每行包含由多个空格和可能的其他符号分隔的数据。我想逐行解析数据,从每行中检索某些组件。解析C++中的大文本文件

我已经编写了一个程序,用于打开输入文件和输出文件,逐行解析输入文件,将行分解为适当的标记并重新构建所需格式的新行,并立即输出到输出文件中。

问题是,当我运行它时,解析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; Metody realizacji巴兹danych; 2004/TL; 3; 2; LONG_CODE_THAT_IM_NOT_SUPPOSED_TO_SHOW”。

我会另外提到,当我一点一点做到这点时,即第一个50k行,然后告诉程序(通过硬编码它跳过第一个50k行)从50k + 1行开始等,没有问题 - 我得到了应有的确切输出。另一方面,当我告诉它每隔5万行关闭文件时,重新打开它们并循环到输入文件的正确行,然后我仍然遇到同样的问题。

编辑2:我编译成调试和使用GDB - 围绕关键线数正确地得到了线(欢呼),但卡在iss >>代码。我在CLion中使用调试器,所以它在一段时间后才超时。

+3

和你有没有尝试使用真正的调试器打入并看看发生了什么? – pm100

+1

内循环看起来非常可疑。如果没有“20”事件怎么办?我也不喜欢那个没有大括号的“if”。 – pm100

+0

发布它处理的最后一行的内容。另外,请修复您的缩进。 – xaxxon

使用cout并不总是最好的调试方式,因为我发现它有时会让程序的终端/整体速度变得糟糕。您可以尝试使用断言或实际的调试器(如GDB)来调试您的程序。一个调试器会引导你通过你的代码,并告诉你到底发生了什么。

+0

谢谢你的建议。我试着再次调试,发现有一个错误的输入,导致我的代码进入一个永恒的循环。 –

+0

很高兴知道你明白了。如果您还没有:),请务必提高答案:) –

+0

问题是,我从许多人的评论中收集了答案(加上你的答案)......我也无法提高答案,因为我没有还有15位代表:/我想代表5位代表回答问题,并感谢其他两位代表提出改进代码的建议。 –

我确实有一个错误的日期 - 检查“20”导致程序进入一个永恒的循环。我要感谢pm100和George Sovetov指出那些代码有潜在危险。我使用调试器来查找问题 - 我感谢Developer和pm100提供的建议。感谢gudok,我用了一张支票来看看是否>> tmp有效,这让我注意到我的循环会变得过于永恒。

我会修复代码并使用正则表达式来希望避免任何其他形式的此类错误(按照knivil的建议)。我也会用'\ n'而不是std :: endl,就像kchinger提出的那样。谢谢各位的评论! :)