我正在编写一个用C ++搜索非常大的文本文件的程序。
该文件是2100万行代码,是系统文件的备份。我试图找到存储在代码中的警报并将它们打印到单独的文本文件中。
来自以下评论。我无法安装任何外部文件或程序,它正在Windows Server 2012上运行。
目前,当我从文本文件中取几千行时,我的代码可以找到第一个警报字符串。但是当我运行完整的1GB加文本文件时,它不会返回任何结果。它只是略过了结果。我已经尝试分配更多的内存和数组,似乎没有正常工作(我可能编码错了我不是最好的C ++编码器,我正在学习,我去)
我的问题是为什么它会在较小的文件上运行,是否是内存问题?我需要将每一行存储为字符串,然后搜索该行,不会花费更长的时间吗?
我的代码如下:
// Alarms.cpp : Defines the entry point for the console application.
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
using namespace std;
int main(){
system("cls");
string PRIORITY_NAME, line;
//bool found = false;
ifstream myfile("fhx.txt");
ofstream alarmList("alarmlist.txt");
int counter = 0;
cout << "Searching for Alarms and sending to AlarmList.txt \n";
//make sure files are good and open and determine size
if (myfile.is_open() && alarmList.is_open())
{
cout << "File is open \n";
ifstream file("fhx.txt", ios::binary | ios::ate);
cout << "The current open file size is " << file.tellg() << " bytes \n";
system("pause");
}
else
{
cout << "File is not open \n";
system("pause");
}
cout << "Running \n"; // show program is running for user to see
// reads the file and searches while there is still a line
while (getline(myfile, line))
{
++counter;
cout << counter << "\n"; //print out lines scanned for debug purposes
// searches the file for PRIORITY_NAME
if (line.find("PRIORITY_NAME") != string::npos)
{
alarmList << line << "\n"; // [rint results to seperate text file
//getline(myfile, line);
cout << line << "\n";// print to console for debug
}
}
alarmList << "\n" << counter << " lines searched\n";
system("pause");
}
这是我运行较小的2千行文件
时的打印输出 PRIORITY_NAME="LOG"
PRIORITY_NAME="LOG"
PRIORITY_NAME="LOG"
PRIORITY_NAME="LOG"
PRIORITY_NAME="LOG"
PRIORITY_NAME="LOG"
PRIORITY_NAME="LOG"
PRIORITY_NAME="LOG"
PRIORITY_NAME="LOG"
PRIORITY_NAME="LOG"
PRIORITY_NAME="LOG"
PRIORITY_NAME="LOG"
PRIORITY_NAME="LOG"
PRIORITY_NAME="LOG"
PRIORITY_NAME="LOG"
PRIORITY_NAME="LOG"
PRIORITY_NAME="LOG"
PRIORITY_NAME="LOG"
搜索了1679行
这是我正在搜索的代码的片段,它是2100万行这样的第一个警报,直到17,000。不幸的是,我不能提供比这更多的东西:
OPERATOR_SUBSYSTEM
{
ENABLED=T
GLOBAL_ALARM_ACK_GROUP=1
RESTRICT_WRITES_TO_AREAS=T
AREA { NAME="AREA_A" }
AREA { NAME="K-401_SYS" }
AREA { NAME="UTIL_AUX" }
AREA { NAME="SIS" }
AREA { NAME="SIS_F201_MOD" }
AREA { NAME="SIS_COKER" }
AREA { NAME="SIS_VRU" }
AREA { NAME="SIS_F202_MOD" }
AREA { NAME="SIS_F203_MOD" }
AREA { NAME="SISCD201_2_SEQ" }
AREA { NAME="SISCD203_4_SEQ" }
AREA { NAME="SISCD205_6_SEQ" }
AREA { NAME="F-201_MOD" }
AREA { NAME="COKE_CUTTING" }
AREA { NAME="CRANE" }
AREA { NAME="FRACT_TWR" }
AREA { NAME="CD201_2_SEQ" }
AREA { NAME="ANTI_FOAM" }
AREA { NAME="MRX_COS" }
AREA { NAME="FIRE_GAS" }
AREA { NAME="ABS_STPR" }
AREA { NAME="BD_SYS" }
AREA { NAME="C3C4_SPLIT" }
AREA { NAME="CD203_4_SEQ" }
AREA { NAME="CD205_6_SEQ" }
AREA { NAME="DEBUT" }
AREA { NAME="DRUM_SEQ_OVW" }
AREA { NAME="F-202_MOD" }
AREA { NAME="F-203_MOD" }
AREA { NAME="FEED" }
AREA { NAME="NAPH_PRETREATER" }
AREA { NAME="S_E_SYS" }
AREA { NAME="T-403_AMINE" }
AREA { NAME="P203_204" }
}
REMOTE_OPERATION_NETWORK_SUBSYSTEM
{
ENABLED=F
COMMUNICATION_TYPE=SIMPLEX
TIMEOUT_INTERVAL=400
NETWORK_TYPE=REMOTE_NETWORK
ENCRYPTION=F
NTP_SERVER="0.0.0.0"
NTP_BACKUP="0.0.0.0"
}
TERMINAL_SERVER_SUBSYSTEM
{
ENABLED=T
}
VIRTUAL_SIS_NETWORK
{
}
ATTRIBUTE_INSTANCE NAME="ADVISE_ALM"
{
VALUE
{
PRIORITY_NAME="LOG"
ENAB=T
INV=F
ATYP="Change From Normal"
MONATTR=""
ALMATTR="ADVISE_ALM"
LIMATTR=""
PARAM1=""
PARAM2=""
SUPPTIMEOUT=1438560
MASK=65535
ISDEFAULTMASK=T
ALARM_FUNCTIONAL_CLASSIFICATION=0
}
EXPLICIT_OVERRIDE=T
VALUE_CHANGED=T
HAS_DEFAULT_VALUE=F
}
非常感谢任何帮助。我愿意尝试和学习任何东西。我想知道我是否需要使用&#34; vector&#34;但我还在读如何正确使用它。
答案 0 :(得分:4)
分配内存以读取整个文件只是为了找到内部的字符串听起来像一个非常糟糕的主意,而且是不必要的。我很确定你也应该使用neiter ios::ate
(从文件末尾开始而不是从开头开始)和binary
(它是文本文件......)。
我认为这是“你不必写这个,它已经完成”的情况;只需使用像grep
这样的工具,该工具几乎适用于任何操作系统:
grep "PRIORITY_NAME" fhx.txt > alarmlist.txt
将完全执行您的程序应该做的事情,可能会更快,并且调试得很好。
答案 1 :(得分:0)
// reads the file and searches while there is still a line
while (getline(myfile, line))
{
++counter;
cout << counter << "\n"; //print out lines scanned for debug purposes
// searches the file for PRIORITY_NAME
if (line.find("PRIORITY_NAME") != string::npos)
{
alarmList << line << "\n"; // [rint results to seperate text file
//getline(myfile, line);
cout << line << "\n";// print to console for debug
}
line.clear();
}
如果在上面的代码中,如果你想要做的就是找到&#34; PRIORITY_NAME&#34;在逐行的基础上,然后您可以在完成每一行后清除流。 就在while循环的下一次迭代之前,也许明确会有所帮助。
line.clear()