2015-05-26 34 views
0

我有一個文件,我想在一行中搜索特定的字符串,然後比較該字符串通過由5000lines組成的整個文件。所有與該字符串匹配的行將被寫入另一個下面的文本文件。到目前爲止,我已經成功地從第一行中獲取該特定字符串,並寫入與特定字符串匹配的所有行。遵循的是隻爲第一行解決問題的代碼。從一行中找到一個特定的字符串通過所有的文件

#include <iostream> 
#include <fstream> 

using namespace std; 

//gets the specific string from first line 
string FirstLineSplitedString() 
{ 
ifstream infile; 
infile.open("test.txt"); 
//prints first line 
string fline; 
string splited; 
if (infile.good()) 
{ 
string sLine; 
getline(infile, sLine); 
fline = sLine; 

//string starting from Cap900 till before .waa (specific string) 
int first = fline.find('_'); 
int last = fline.find_last_of('.'); 
splited = fline.substr (first+1,last-first); 

} 
return splited; 
} 


int main() 
{ 
string SString = FirstLineSplitedString(); 
ifstream stream1("test.txt"); 
string line ; 
ofstream stream2("output.txt"); 

while(std::getline(stream1, line)) 
{ 
if(line.find(SString) != string::npos) 
    stream2 << line << endl; 
} 


stream1.close(); 
stream2.close(); 
    return 0; 
} 

我不知道該怎麼做:我不知道如何做到這一點所有的文件。我的意思是,當我完成從第一行中找到特定的字符串並寫入與字符串匹配的所有行時,如何進入下一行並執行相同的步驟,並將所有行與匹配的字符串相互對齊。此外,如果沒有匹配,只有線本身將寫入文件。

例如:可以說,我有一個包含以下內容(以粗體)

AAAAAA _men這兒有文件test.txt。那裏。等
bbbb _men there here。那裏。
aaaabbbbbaa _from from。那裏。所以
zzzzzzzz _from from。那裏。這裏有
aaabbbbbaaa _men。那裏。所以在這裏
aabbbbaaaa _men。那裏。等
nnnnnnn _from from。那裏。等

當我在output.txt中運行代碼我得到以下幾行
AAAAAA _men這裏有

。那裏。等
bbbb _men there here。那裏。這裏有
aaabbbbbaaa _men。那裏。所以在這裏
aabbbbaaaa _men。那裏。等等

這是正確的,因爲我想拆分得到特定的字符串從(_)到最後(。)。現在我想把它與第一行不同,並得到結果。下面是我想從test.txt獲得的output.txt文件

aaaaaa _men there here。那裏。等
bbbb _men there here。那裏。這裏有
aaabbbbbaaa _men。那裏。所以在這裏
aabbbbaaaa _men。那裏。等


aaaabbbbbaa _from from。那裏。所以
zzzzzzzz _from from。那裏。等
nnnnnnn _from from。那裏。等


這種模式應該繼續,直到文件

遺憾的AST線寫了這麼長時間,但我想盡可能清晰。任何幫助將不勝感激。
也不要忘記,匹配特定字符串的行可能會低於對方或可能會在2000行之後。

+0

您可以編輯您的問題補充更多的信息,而不是留下評論。 – Emadpres

+0

我想我在範圍時間內越過了編輯限制。所以我現在就按照你的提醒去做。 –

回答

0

所以我想你需要根據組中一些子鍵輸入文件中的行。

最簡單的方法是將填充內存線組的集合作爲您讀文件,然後處理後的整個輸入刷新組到輸出文件:

#include <iostream> 
#include <string> 
#include <fstream> 
#include <deque> 

using namespace std; 

string findGroupKey(const string &line) 
{ 
    size_t first = line.find('_'); 
    if (first == string::npos) 
     first = 0; 
    size_t last = line.find_last_of('.'); 
    size_t len = (last == string::npos ? string::npos : last - first + 1); 
    // The key includes the start and end chars themselves in order to 
    // distinguish lines like "x_test." and "xtest" 
    return line.substr(first,len); 
} 

int main() 
{ 
    // *** Var defs 
    // Read the input file as stream 
    ifstream inStream("test.txt"); 
    // line by line placing each just read line into inLine 
    string inLine; 
    // Place each inLine into its one group 
    deque<deque<string> *> linesGrouped; 
    // according to the grouping key 
    deque<string> keys; 

    // *** Read the input file and group the lines in memory collections 
    while (getline(inStream, inLine)) { 
     string groupKey = findGroupKey(inLine); 

     // Find the key in our keys-met-so-far collection 
     int keyIndex = -1; 
     for (int i = 0, keyCount = (int)keys.size(); i < keyCount; i++) 
      if (keys.at(i) == groupKey) { 
       keyIndex = i; 
       break; 
      }; 

     if (keyIndex == -1) { 
      // If haven't found the key so far, add it to our key index collection 
      keys.push_back(groupKey); 
      // and add a new group collection 
      deque<string> *newGroup = new deque<string>(); 
      newGroup->push_back(inLine); 
      linesGrouped.push_back(newGroup); 
     } else { 
      // Otherwise just add the line into its respective group 
      linesGrouped.at(keyIndex)->push_back(inLine); 
     } 
    } 

    // *** Write the groups into the output file 
    ofstream outStream("output.txt"); 
    for (int i = 0, groupCount = (int)linesGrouped.size(); i < groupCount; i++) { 
     for (int j = 0, lineCount = (int)linesGrouped.at(i)->size(); j < lineCount; j++) 
      outStream << linesGrouped.at(i)->at(j) << endl; 
     // Add a delimiter line (uncomment if you need one) 
     //if (i < groupCount - 1) 
     // outStream << "-------------------" << endl; 
    } 
    return 0; 
} 
+0

@Egorov感謝egorov,但發現無法在代碼塊中編譯您的代碼。雖然我包括。我將不勝感激,如果你改變它,以便與我運行的代碼塊兼容,並看到結果。 –

+0

固定爲與代碼塊兼容。使用MinGW的gcc 4.4.0進行編譯。更新的代碼現在在原始答案中。你用這個版本的工具鏈行嗎?我應該嘗試其他方法,例如MS VC嗎?順便說一句,有沒有必要在

+0

非常感謝葉戈羅夫我沒有測試過整個文件,但我看起來它的工作如預期:)。我想給你一個投票,但還沒有得到這個聲譽,但當我得到我肯定會做:) –

0

我做了新的變化,我認爲現在的工作和最簡單的方法:

#include <iostream> 
#include <fstream> 
#include <vector> 
#include <set> 

using namespace std;  

int main() 
{ 
    string line,splited; 
    int current_line = 0, first = 0, last = 0; 
    ifstream stream1("test.txt"); 
    ofstream stream2("output.txt"); 

    //Set when I'm going to save those distinct keys (splited string) 
    set<string>insertedKeys; 
    vector<string>my_array; 

    while(std::getline(stream1, line)) 
    { 
     first = line.find('_'); 
     last = line.find_last_of('.'); 
     splited = line.substr (first+1,last-first);   
     insertedKeys.insert(splited);   
     my_array.insert(my_array.end(), line); 
     //cout << line << endl;    
    } 


    //Then, for each key in insertedKeys you're going to find and save in output.txt those lines that match against the current key 
    std::set<string>::iterator it = insertedKeys.begin(); 
    for (it ; it != insertedKeys.end(); ++it){ 
     string current_key = *it; 
     for(int i=0 ; i< my_array.size() ; i++){ 
      line = my_array[i]; 
      if(line.find(current_key) != string::npos){ 
       stream2 << line << endl;  
      } 
     } 
     stream2 << " ----------------------------------------------------------------------- " << endl;  
    } 
} 
+0

@Sangoi首先,我很欣賞你的時間和努力。我檢查了你的代碼並理解了它,但它不工作。即使是隻有一行符合字符串的基礎,那麼只有該行應該寫入該文件,它將同一行寫入2次。其次,對於不止一行,它只是做不同的事情。我試圖找出爲什麼代碼行爲如你所說的非常合乎邏輯,應該工作的奇怪。請觀察一下,看看是否有什麼我們都錯過了。期待聽到你的消息。再次感謝。 –

+0

感謝上面的更正。我認爲它現在正在工作。基本上,程序將在文件「test.txt」中查找每個模式('_'和'。'之間的字符串)。然後它將在output.txt中寫入與每個模式匹配的那行。如果你不喜歡什麼,請立即告訴我。 –

+0

Sangoi謝謝。正如在上面的帖子Egorov和我昨天解決了這個問題,我沒有檢查你的最後一篇文章,但肯定如果你有檢查編輯它然後它一定是工作。在這3天4天裏,我從這個網站學到了很多,這要歸功於你的所有努力。在此之後我會更頻繁地使用。祝你有美好的一天。 –

相關問題