2011-08-05 1121 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

相关问题