2015-02-02 3 views
0

Я пишу программу для поиска по очень большому текстовому файлу с C++.Программа на C++ отсутствует искомая строка в больших файлах .TXT. Работает для небольших файлов .TXT

Файл представляет собой 21 миллион строк кода и представляет собой резервную копию системного файла. Я пытаюсь найти тревоги, которые хранятся внутри кода, и распечатывать их в отдельный текстовый файл.

Из комментариев ниже. Я не могу установить какие-либо внешние файлы или программы и запускается в 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 линии искали

Вот фрагмент код, который я ищу, это 21 миллион строк, подобных этому, с первым сигналом тревоги, пока не будет 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 
    } 

Любая помощь очень ценится. Я открыт для изучения и изучения чего-либо. Мне было интересно, нужно ли мне использовать «вектор», но я все еще читаю о том, как правильно его использовать.

+0

Вы знаете, как использовать отладчик? Один шаг через код и выяснить, почему он выходит рано. – flodin

+0

Для этого вам не нужно писать свой код на C++. Вам нужно получить некоторые команды 'grep' или' awk', работающие в вашей ОС. –

+0

Он не выходит рано, он пробегает весь большой текстовый файл и подсчитывает точное количество строк, которое он просто находит 0 результатов. – Cavell219

ответ

4

Выделение памяти для чтения во всем файле, чтобы найти строки внутри звуков, как очень плохие идеи и ненужные. Я уверен, вы также должны использовать neiter ios::ate (начиная с конца файла, а не с начала), а не binary (это текстовый файл ...).

Я думаю, что это случай «вам не нужно писать это, это уже сделано»; просто использовать инструмент, как grep, который должен быть доступен практически для любой операционной системы:

grep "PRIORITY_NAME" fhx.txt > alarmlist.txt 

будет делать именно то, что ваша программа должна делать, возможно, будет быстрее, и хорошо отлажена.

+3

Хотя я согласен, что он не должен «изобретать велосипед», на самом деле это не ответ на его вопрос. Рекомендовать программное обеспечение для замены кода, который он пытается написать, не является причиной того, что SO существует ... –

+0

Спасибо, я не знал о grep, я читаю об этом сейчас. – Cavell219

+0

Позвольте мне убедиться, что я правильно понял: Grep - это отдельная программа, которая должна быть установлена ​​в системе, а затем вызывается через командную строку? Если это так, я не могу его использовать. Я запускаю это на заблокированной системе, в которую нельзя установить. У меня есть разрешение на запуск консольного приложения, но я ничего не могу установить. Наверное, я могу попробовать запустить grep через флешку. – Cavell219

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(); 
     } 

Если в приведенном выше коде, если все, что вам нужно сделать, это найти «PRIORITY_NAME» на построчной основе, то вы можете очистить поток после того, как вы закончите с каждой строки. Как раз перед следующей итерацией цикла while, возможно, ясная помощь.

line.clear() 
+0

Хорошая идея, и я попробовал. Но все же были те же результаты :(Спасибо за предложение. – Cavell219

+0

Тогда проблема не может быть в цикле while. Поскольку вы очищаете вектор, здесь не должно быть проблем, если вы очищаете его в конце каждой итерации. – basav

+0

'ifstream file ("fhx.txt", ios :: binary | ios :: ate); cout << "Текущий открытый размер файла:" << file.tellg() << "bytes \ n"; – basav