需要将文本的特定行写入新文本

时间:2011-08-05 07:28:03

标签: c++ string list sorting text

我的数字文本数据行大小介于1mb到150 mb之间,我需要编写与高度相关的数字行,例如:高度= 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; 
}

3 个答案:

答案 0 :(得分:0)

你需要使用 seekg 设置文件开头的位置,一旦你读完它(你已经读过一次,计算行数(我认为你不需要,因为这个尺码从未使用过,至少在这段代码中

内心while有什么意义?在每个循环中,你有

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

因此,在每个循环中,i得到1,因此您始终输出索引为1的元素。这不是第一个元素,因为索引从0开始。因此,一旦您放置seekg或删除第一个while,您的程序就会开始崩溃。

所以,让i0开始。并将其从while的开头处的两个if-statement循环中取出。

啊,第二个while也是不必要的。只留下第一个。


编辑: 添加

myfile_in.clear();

seekg之前清除标志。

另外,你的算法错了。如果h&gt;你会得到seg错误1,因为你将超出范围(向量)。我建议这样做:阅读while中的文件,它会对行进行计数。并将每一行存储在向量中。这样您就可以删除第二个读数seekgclear等。另外,由于您已将文件内容存储到vector,因此您不会失去任何东西然后只需使用步骤for的{​​{1}}循环。


再次编辑,关于你的编辑:不,它与任何标志无关。比较h的{​​{1}}超出了时间。把它添加到里面。另外,在if之外增加i==j。或者只需删除j并使用if代替。像

j

答案 1 :(得分:0)

有几件事。

首先你完全读完文件,只计算行数, 然后你第二次读它来处理它,建立一个内存 v中的图片。为什么不在第一时间阅读它,并做所有事情 在内存中的其他图片? (v.size()然后会给你这个号码 线条,所以你不必计算它们。)

你从来没有真正使用过计数。

第二,一旦你第一次到达文件的末尾,那么 failbit已设置;所有进一步的操作都是无操作,直到它被重置。 如果你必须阅读两次文件(比如因为你取消v 完全),然后你必须在第一个之后做myfile_in.clear() 循环,但在寻找开始之前。

您只需在阅读一次文件后测试is_open。这个测试 应该在开放后立即。

您也设置了noskipws,但您没有进行任何格式化输入 会受到影响。

最终while非常可疑。因为你没有做过 clear,你可能永远不会进入循环,但如果你这样做了,你就会非常 快速开始访问越界:读取n行后,大小 v的{​​{1}}将为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行。如果是这样的话 案例:

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。)为什么要用你不用的语言编写程序 我们知道什么时候有工具可以用来完成工作。

答案 2 :(得分:-1)

如果没有绝对令人信服的理由在C ++中这样做,那么你使用错误的编程语言。在awk中,您的整个程序是:

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

或者,给出整个命令行,例如在sh中过滤行1,5,9,13,...:

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