我有一个约250k行的文本文件。每行包含由多个空格和可能的其他符号分隔的数据。我想逐行解析数据,从每行检索某些组件。
我编写了一个打开输入文件和输出文件的程序,逐行解析输入文件,将行拆分为适当的标记,然后重新构建所需格式的新行,并立即输出到输出文件中。< / p>
问题是,当我运行它时,它在解析70到92k行后停止。通过档位我的意思是程序仍然运行,但它不处理任何事情,我的终端中的光标只是停留在那里并闪烁。通过使用愚蠢的调试(使用cout),我检查了第92521行,它确实采用了输入行(正确的行),但它没有通过分解标记和重建格式良好的行而只是停止。< / p>
下面我附上相关代码。我期待有人告诉我发生了什么,即为什么我的程序停滞不前以及我可以用什么方式解决这个问题。谢谢你的关注!
#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 baz danych; 2004 / TL; 3; 2; LONG_CODE_THAT_IM_NOT_SUPPOSED_TO_SHOW”。
我还要提到的是,当我一点一点地进行,即前50k行,然后告诉程序(通过硬编码跳过前50k行)从50k + 1行开始等没有问题 - 我得到了我应该的确切输出。另一方面,当我告诉它每隔50k行关闭文件时,重新打开它们并循环到输入文件的正确行,然后我仍然遇到同样的问题。
Edit2:我把它编译成调试并使用了gdb - 围绕它正确排队的关键行数(hurray),但卡在了问题&gt;&gt;码。我在CLion中使用调试器,所以它在一段时间后才超时。
答案 0 :(得分:1)
使用cout并不总是最好的调试方式,因为我发现它有时会降低程序的终端/整体速度。您可以尝试使用断言或实际的调试器(例如GDB)来调试程序。调试器将引导您完成代码,并向您展示发生在幕后的内容。
答案 1 :(得分:0)
我确实有一个错误的日期 - 检查&#34; 20&#34;导致程序进入一个永恒的循环。我要感谢pm100和George Sovetov指出这段代码有潜在危险。我使用调试器来查找问题 - 我感谢Developer和pm100建议这样做。感谢gudok,我用了一张支票来查看是否有&gt;&gt; tmp有效,这让我注意到我的循环会变得过于永恒。
我将修复代码并使用正则表达式来避免任何其他形式的此类错误(根据knivil的建议)。我还会使用&#39; \ n&#39;而不是std :: endl,kchinger提出的方式。感谢所有人的评论! :)