需要将文本的特定行写入新文本
Posted
技术标签:
【中文标题】需要将文本的特定行写入新文本【英文标题】:Need to write specific lines of a text into a new text 【发布时间】:2011-08-05 07:28:03 【问题描述】:我有大小在 1mb - 150 mb 之间的数字文本数据行,我需要编写与高度相关的数字行,例如: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;
【问题讨论】:
“恒定高度增加” ???请改写您的问题。目前无法理解 【参考方案1】:您需要使用 seekg
设置文件开头的位置,一旦你读过它(你读过一次,计算行数(我认为你实际上不需要,因为这个size 从未使用过,至少在这段代码中)
如果内部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 > 1,你会得到段错误,因为你会超出(向量的)范围。我建议这样做:读取while
中的文件,它计算行数。并将每一行存储在向量中。这样您就可以删除第二个读数seekg
、clear
等。此外,由于您已经将文件内容存储到vector
中,因此您不会丢失任何内容。然后只需使用for
循环和步骤h
。
再次编辑,关于您的编辑:不,它与任何标志无关。与i==j
进行比较的if
在while 之外。把它加进去。此外,在if
之外增加j
。或者只是删除j
并改用n-1
。喜欢
if ( n-1 == i )
【讨论】:
【参考方案2】:几件事。
首先你完全阅读文件,只是为了计算行数,
然后你第二次阅读它来处理它,在内存中建立一个
图片在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
-th 行。如果这是
案例:
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。)为什么要使用您不使用的语言编写程序 知道什么时候已经可以使用工具来完成这项工作。
【讨论】:
感谢您的输入,我正在尝试从文本中提取一些行并将其写入另一个...我已经清理了我之前只读一次的代码system("pause")
表示提问者在windows上运行。因此,使用sed
是一个奇怪的建议 :-)
遵循 thiton 的建议可能是最容易做的事情,但是我对 awk 一无所知。它会从我的文本文件中读取并写入新文件吗?
@tyz 我经常在 Windows 上使用sed
:-)。毫无疑问,有一些原生的 Windows 等价物可以用来代替它,但我还没有找到。如果你要在平台上开发软件,你肯定需要某种具有这种功能的工具包。【参考方案3】:
如果没有绝对令人信服的理由在 C++ 中执行此操作,则说明您为此使用了错误的编程语言。在 awk 中,你的整个程序是:
if ( FNR % 4 == 1 ) print;
或者,给出整个命令行,例如在 sh 中过滤第 1、5、9、13 行,...:
awk ' if ( FNR % 4 == 1 ) print; ' a.txt > b.txt
【讨论】:
这可能是最简单的事情,但是我对 awk 一无所知。它会从我的文本文件中读取并写入新文件吗? 是的,这是基本的操作模式。假设你有一个文本文件 a.txt 并想写入 b.txt,命令行 awk ' if ( FNR % 4 == 1 ) print; ' a.txt > b.txt 完成这项工作。以上是关于需要将文本的特定行写入新文本的主要内容,如果未能解决你的问题,请参考以下文章