2011-08-05 354 views
0

我有數字文本數據行,大小在1mb-150mb之間,我需要寫出與高度有關的數字行,例如:heights = 4,新文本必須包括行:1,5,9,13,17,21 ....因此。需要將文本的特定行寫入新文本

我一直在試圖找到一種方法來做到這一點,現在嘗試使用列表而不是矢量結束了編譯錯誤。

我已經清除了建議的代碼。它現在寫入所有行sample2文本,全部在這裏完成。謝謝大家

只要它提供我需要的東西,我就會接受方法更改,感謝您的時間和幫助。

以下是我迄今爲止:

#include <iostream> 
#include <fstream> 
#include <string> 
#include <list> 
#include <vector> 

using namespace std; 

int h,n,m; 
int c=1; 

int main() { 

cout<< "Enter Number Of Heights: "; 
cin>>h; 

ifstream myfile_in ("C:\\sample.txt"); 
ofstream myfile_out ("C:\\sample2.txt"); 
string line; 
std::string str; 
vector <string> v; 
if (myfile_in.is_open()) { 
myfile_in >> noskipws; 
int i=0; 
int j=0; 
while (std::getline(myfile_in, line)) { 
v.push_back(line); 
++n; 
if (n-1==i) { 
myfile_out<<v[i]<<endl; 
i=i+h; 
++j; 
} 
    } 
cout<<"Number of lines in text file: "<<n<<endl; 
} 

else cout << "Unable to open file(s) "; 

cout<< "Reaching here, Writing one line"<<endl; 

system("PAUSE"); 
return 0; 
} 
+0

「恆定高度添加」?請改述你的問題。在目前狀態 – Arunmu

+0

和..yeah ..無法理解,歡迎來到:) – Arunmu

+0

完成...謝謝:) – Mario

回答

0

您需要使用seekg設置在文件的開頭位置,一旦你讀它(您曾經閱讀,計數線(我不認爲你確實需要,因爲這個尺寸是從來沒有使用過,至少在這段代碼)

,什麼是點如果內部while?在每個循環中,你有

int i=1; 
myfile_out<<v[i]; //Not writing to text 
i=i+h; 

因此,在每個循環中,i獲得1,因此您始終輸出索引爲1的元素。這不是第一個因素,因爲指數從0開始。所以,一旦你把seekg或刪除第一個while,你的程序將開始崩潰。

因此,使i0開始。並從循環中取出它,就在if-statement的開頭。

嗯,第二個while也是不必要的。只留下第一個。


編輯: seekg之前添加

myfile_in.clear(); 

清除標誌。

另外,你的算法是錯誤的。如果h> 1,你會得到seg故障,因爲你會超出範圍(矢量)。我建議這樣做:讀取while中的文件,這些文件包含在內。並將每行存儲在向量中。通過這種方式,您可以刪除第二個閱讀文本,seekg,clear等。此外,由於您已將文件內容存儲到vector,因此您不會丟失任何內容。然後,使用for循環與步驟h


再次編輯,關於你的編輯:不,它與任何標誌無關。 if,你比較i==j是在時間之外。把它添加進去。另外,在if之外增加j。或者只是刪除j並改用n-1。像

if (n-1 == i) 
+0

@Mario - 再次,關於你最後的編輯,請看我的:D –

+0

It作品:D,謝謝你隊友! – Mario

+0

不客氣:) –

-1

如果在C++中沒有絕對有說服力的理由這麼做,那麼您使用的是錯誤的編程語言。在awk中,您的整個程序是:

{ if (FNR % 4 == 1) print; } 

或者,給出整個命令行例如在sh過濾行1,5,9,13,...:

awk '{ if (FNR % 4 == 1) print; }' a.txt > b.txt 
+0

這可能是最簡單的事情,但我對awk一無所知。它會從我的文本文件中讀取並寫入新文件嗎? – Mario

+0

是的,那是基本的操作模式。假設你有一個文本文件a.txt並且想寫入b.txt,命令行 awk'{if(FNR%4 == 1)print; }'a.txt> b.txt 完成這項工作。 – thiton

0

幾件事。

首先你仔細閱讀本文件,只需計算行數,然後 你讀它第二次來處理它,在v建立一個在內存 圖像。爲什麼不在第一次閱讀它,並在內存映像中執行其他所有內容呢? ? (v.size()會給你的線路號碼 ,所以你不必數它們。)

而且你從來沒有真正使用計數。

其次,一旦您第一次到達文件末尾,就會設置爲 failbit;所有進一步的操作都是空操作,直到它被重置。 如果你必須兩次讀取文件(說因爲你完全消除v ),那麼你必須做myfile_in.clear()後第一個 循環,但在尋求開始之前。

您僅在讀取一次文件後才測試is_open。這個測試 應該在打開後立即進行。

您還設置了noskipws,雖然您不會進行任何格式化輸入 ,它會受到它的影響。

最後的while是高度懷疑。因爲你還沒有完成 clear,你可能永遠不會進入循環,但如果你這樣做,你會很快開始訪問越界:讀取n行後,v的大小 將是n,但是你閱讀索引i,這將是n * h

最後,您應該明確關閉輸出文件,並檢查 錯誤關閉,以防萬一。

我不清楚你想要做什麼。如果你想要做的是 插入h每個現有行之間的空行,像:

std::string separ(h + 1, '\n'); 
std::string line; 
while (std::getline(myfile_in, line)) { 
    myfile_out << line << separ; 
} 

應該做的伎倆。無需將完整的輸入存儲在內存中。 (對於這個問題,你甚至不必爲此編寫程序。 簡單的sed 's:$:\n\n\n\n:' <infile> outfile會做 的竅門。)

編輯:

閱讀其他答覆,據我瞭解,我可能誤解了 問題,他只希望輸出每h n行。如果這是 的情況:

std::string line; 
while (std::getline(myfile_in, line)) { 
    myfile_out << line << '\n'; 
    for (int count = h - 1; h > 0; -- h) { 
     std::getline(myfile_in, line); 
     // or myfile_in.ignore(INT_MAX, '\n'); 
    } 
} 

但是,其他工具似乎更合適。 (我會遵循thiton的 建議並使用AWK。)爲什麼用一種你不懂的語言編寫程序時,你知道何時可以使用工具來完成這項工作。

+0

感謝您的輸入,我試圖從文本中提取一些行並將其寫入另一個...我已經清理了以前只讀一次的代碼 – Mario

+0

'system(「pause」)'表示提問者在Windows上運行它。因此,在thiton的建議之後使用'sed' :-) –

+0

可能是最簡單的事情,但我對awk一無所知。它會從我的文本文件中讀取並寫入新文件嗎? – Mario

相關問題