我的数字文本数据行大小介于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;
}
答案 0 :(得分:0)
你需要使用 seekg
设置文件开头的位置,一旦你读完它(你已经读过一次,计算行数(我认为你不需要,因为这个尺码从未使用过,至少在这段代码中
内心while
有什么意义?在每个循环中,你有
int i=1;
myfile_out<<v[i]; //Not writing to text
i=i+h;
因此,在每个循环中,i
得到1,因此您始终输出索引为1
的元素。这不是第一个元素,因为索引从0
开始。因此,一旦您放置seekg
或删除第一个while
,您的程序就会开始崩溃。
所以,让i
从0
开始。并将其从while
的开头处的两个if-statement
循环中取出。
啊,第二个while
也是不必要的。只留下第一个。
编辑: 添加
myfile_in.clear();
在seekg
之前清除标志。
另外,你的算法错了。如果h&gt;你会得到seg错误1,因为你将超出范围(向量)。我建议这样做:阅读while
中的文件,它会对行进行计数。并将每一行存储在向量中。这样您就可以删除第二个读数seekg
,clear
等。另外,由于您已将文件内容存储到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