正在设置文件指针位置
Setting file pointer position
- 我有一个很大的文本文件,里面有很多按行排列的条目
- 每行的第一个单词对我来说就像一个">键"。这行的其他单词都是数字
- 一行的第一个字也可以存在于大量其他行中
作为一个例子,考虑如下文件的示例:
Associative 19 78 45 23
Disjunctive 23 45 02 200
Associative 23 546 32 56
Conjunctive 22 22 00 3478
Disjunctive 11 934 88 34
我的目标:
对所有"联想词"、"虚拟词"answers"连接词"做一组特定的运算。该文件很大,未进行排序。我可以使用bash进行额外的排序操作,但只考虑我想避免它的情况
我的方法:
Step 1 : Open the file using **std::ifstream**
Step 2 : Create an unordered set to store the unique first words.
Step 3 : Create a multimap of type multimap<std::string,streampos>
Step 4 : Traverse the file using std::ifstream::ignore, and keep adding the first word to the unordered set, and stream position to the multimap alongwith the first word.
Step 5 : The thought is that in this way a primary index of stream position and line numbers is being created.
Step 6 : Now go through each element of the unordered set and use multimap::equal_range to look for stream positions for that key.
Step 7 : Traverse through those stream positions and do your operation
Q1.使用C++从文件中读取特定行的方法正确吗?
Q2.下面是我为测试这个想法而编写的C++程序的一个基本片段。然而,我觉得这个想法不会成功。程序已完成。您可以简单地复制和粘贴代码,并使用上面的文本文件示例来查看输出。具体问题如下:当我使用seekg设置流位置,然后尝试读取一行时,似乎什么都没发生(即流位置没有改变(。代码片段如下:
#include<iostream>
#include<fstream>
#include<limits>
#include<unordered_set>
#include<map>
using namespace std;
int main(int argc,char* argv[])
{
if (argc<2)
{
cout<<"Usage: get_negatives <Full Path of Annotation File> n"<<endl;
return 0;
}
ifstream fileGT;
fileGT.open(argv[1]);//Open the file containing groundtruth annotations
string filename;
unordered_set<string> unique_files; //Open this unordered set to uniquely store the file names
multimap<string,streampos> file_lines; //Open this multimap to store the file names as keys and corresponding line numbers as the values
streampos filepos = fileGT.tellg();
fileGT>>filename;
unique_files.insert(filename);
file_lines.insert(pair<string,streampos>(filename,filepos));
while(!fileGT.eof())
{
fileGT.ignore(numeric_limits<streamsize>::max(),'n');
filepos = fileGT.tellg();
fileGT>>filename;
unique_files.insert(filename);
file_lines.insert(pair<string,streampos >(filename,filepos));
}
for(auto it=unique_files.begin(); it!=unique_files.end(); ++it)
{
pair<multimap<string,streampos>::iterator, multimap<string,streampos>::iterator>range_vals;
range_vals = file_lines.equal_range(*it);
for(auto it2=range_vals.first; it2!=range_vals.second; ++it2)
{
fileGT.seekg(it2->second,ios_base::beg);
getline(fileGT,filename);
cout<<filename<<endl;
}
}
return -1;
}
问题是,如果设置了一些错误位,seekg()
有时无法正常工作。
您必须始终在每次fileGT.seekg()
之前调用fileGT.clear()
。我认为这应该是C++11中的默认模式,但我不会打赌。
此外,在每次读取后检查错误也是一个好主意:
if (!getline(fileGT, filename))
//error handling
而且,正如我在评论中所说,如果你要四处寻找,你必须用std::ios::binary
打开文件。
我还没有测试你的代码,但我建议你做一些更改:
-
我遇到的大多数操作系统都使用约定,用于main的返回值,
return 0
用于典型/正确输出,return 1
(或非零(用于异常情况。 -
除非你真的需要,否则不要使用
n
和endl
,我认为这不是千种情况之一。 -
考虑重新排序
while
循环,使ignore
位于末尾,考虑以下内容:
std::string buf;
std::ifstream fp("input");
while (fp)
{
if (fp >> buf) { /* do something with buf */ }
fp.ignore(streamsize::max(), 'n');
}
无论何时从流中读取,都不要认为输出良好或流仍然有效。检查错误标志(使用bool重载或
fp.good()
(。仅仅检查fp.eof()
可能并不总是足够的。如果您使用的是C++11
seekg
,即使在到达文件末尾后也应该运行良好,但在早期的变体中,您需要使用fp.clear()
清除流错误位。如果你没有用C++11进行编译,
auto
关键字可能不会起到你认为的作用,请小心。您可能还需要考虑const auto&
。
- 如何使用cudaMallocManaged在指针位置初始化对象?(C++)
- C++指针数组到字符数组中的特定位置
- 声明指针时更改星号的位置
- 如何在单个链表中交换两个节点的位置,只修改指针
- 当原始数据是常量时,修改指针指向的位置是 UB 吗?
- 如果访问对象,则指向的对象内部的指针会更改内存位置
- 访问违规读取位置传递指针以在c中写入的DLL中起作用
- 如何在内存位置取消指针,并用值启动它
- C++ - 智能指针 - 访问冲突读取位置0xDDDDDDDD
- 最简单的方法使多个指针一次指向同一位置,一次只处理2个位置
- 在指针中保存确定的位置
- 试图读取AIFF文件意外错误与指针位置等有关
- 如何在 c++ 中查找文件指针位置
- QTableView并设置指针位置
- 字符串和指针位置
- 对齐C++指针位置的目的是什么
- 正在尝试访问指针位置中的值,并获取seg错误
- C++中的平均指针位置
- 从内存中移除指针位置的项
- 正在设置文件指针位置