我有一个这样的文本文件:
1 0.05 -7
2 0.1 -4
3 0.11 -1
4 0.12 -3
3 0.15 -2
4 0.2 0
5 0.25 8
我要找的是从最后一行读取C ++中的文本文件,到达以4开头的行,将该行的值保存在数组中,然后继续到达以2开头的行并再次保存与此行对应的值。
从最后一行开始对我来说非常重要,因为我查找时间步骤4的最后更新值。
当我正在寻找这个向量4 0.12 -3
4 0.2 0
答案 0 :(得分:2)
实现这一点真的不是一件轻而易举的事。除非文件非常庞大(100MGB或更多),否则最好的方法可能就是将整个内容简单地读入一个向量中,并在内存中处理它[以您选择的顺序排列,因为您现在可以将其视为任何向量输入它,因此"随机访问"]。
有可能从末尾向后移动,但它很尴尬。像这样的东西会从后到前读取整个文件:
ifstream f("somefile.txt");
char c;
// Place get position at one from last.
f.seekg(-1, ios_base::end);
while(f.get(c))
{
... process character ...
// Move back two (because get moved forward one, and
// we want the one before that.
f.seekg(-2, ios_base::cur);
}
然后你必须记住你的字符串是向后的,所以你必须先添加而不是追加。
答案 1 :(得分:1)
我的点操作策略是逐行扫描所有文件,在内存中保留两行数组,在每个传入行更新,以便始终包含最新的两行。在EOF
,您的数组包含感兴趣的行。
伪代码:
array[2];
array[0]=array[1]=null;
while(!eof)
{
array[1]=array[0];
array[0]=readline();
}
... do what you want with array[1] and array[0]
array[0]
将包含文件的最后一行array[1]
,但最后一行。
check for null:如果文件只包含一行,或者根本没有行,则可以让数组中的一个或两个条目指向null。
当然,如果文件的大小非常大,那么这是一个非常昂贵的时间,但它是一种简单可靠的解决方案,适用于每个操作之间至少有几分钟数量级的现场操作。
否则,如果需要更频繁的轮询,为什么不继续监视文件?
这是tail -f
程序使用的策略。
答案 2 :(得分:0)
在文本文件中跳转很困难,而且通常非常低效。我建议如下:
将整个文件加载到内存中,仅保留最新结果:
ifstream fin("fname.txt");
// ... Don't forget error checking.
std::unordered_map<int, std::pair<float, int>> entries;
int first, third;
float second;
while (fin >> first >> second >> third) {
entries[first] = make_pair(second, third); // Will overwrite existing.
}
现在,只需访问您要查找的密钥的地图,即可轻松访问最后一个条目。
cout << entries[4]->first << " " << entries[4]->second << endl;
输出:0.2 0
答案 3 :(得分:0)
我想到了两种策略:
1 - 之前提出的:有大小为2或两个变量的数组等...,以保存最后两行读取(如果文件很小,应该非常好用,并且非常直接)
2 - 使用ifstream :: seekg(std :: ios_base :: end)定位在EOF中,然后向后搜索EOL标记(如果文件较大且行与文件相比较小,则应该有效)。使用peek可以检查EOL标记(考虑到不同的EOL标记(\ n \ r,\ n,\ r),这会更复杂,如果行变长则可能会慢。