C++ 设置文件指针位置 我有一个非常大的文本文件,其中包含许多按行排列的条目 每行的第一个字对我来说就像一个“键”。这行的其他单词是数字 一行的第一个字也可以存在于大量其他行中 作为示例,考虑文件的示例如下: 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 #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; }

C++ 设置文件指针位置 我有一个非常大的文本文件,其中包含许多按行排列的条目 每行的第一个字对我来说就像一个“键”。这行的其他单词是数字 一行的第一个字也可以存在于大量其他行中 作为示例,考虑文件的示例如下: 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 #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; },c++,file,C++,File,我的目标: 对所有“联想词”、“析取词”和“连接词”执行一组特定的操作。该文件非常大,未排序。我可以使用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::st

我的目标:

对所有“联想词”、“析取词”和“连接词”执行一组特定的操作。该文件非常大,未排序。我可以使用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
步骤1:使用**std::ifstream打开文件**
步骤2:创建一个无序集来存储唯一的第一个单词。
步骤3:创建类型为multimap的multimap
步骤4:使用std::ifstream::ignore遍历文件,并将第一个单词添加到无序集,并将流位置与第一个单词一起添加到多重映射。
第5步:其思想是通过这种方式创建流位置和行号的主要索引。
步骤6:现在检查无序集合的每个元素,并使用multimap::equal_range查找该键的流位置。
步骤7:遍历这些流位置并执行操作
问题1。使用C++ +

从文件中读取特定行是否正确? 问题2。下面是我编写的C++程序的基本片段来测试这个想法。然而,我不认为这个想法会成功。程序完成了。您可以简单地复制和粘贴代码,并使用上面的文本文件示例查看输出。具体问题如下: 当我使用seekg设置流位置,然后尝试读取一行时,似乎什么都没有发生(即流位置没有改变)。 代码片段如下所示:

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
#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;

}       
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
int main(int argc,char*argv[])
{
if(argcfilename;
唯一的_文件。插入(文件名);
插入(成对(文件名,filepos));
}
对于(自动it=unique_files.begin();it!=unique_files.end();++it)
{
排程;
范围=文件行。相等范围(*it);
对于(自动it2=范围值.first;it2!=范围值.second;+it2)
{
fileGT.seekg(it2->second,ios_base::beg);
getline(fileGT,filename);

cout问题在于,如果设置了一些错误位,则
seekg()
有时无法正常工作

在每次调用
fileGT.seekg()
之前,您必须始终调用
fileGT.clear()
。我认为这应该是C++11中的默认模式,但我不敢打赌

此外,最好在每次读取后检查错误:

if (!getline(fileGT, filename))
    //error handling

而且,正如我在评论中所说的,如果你想四处寻找,你必须用
std::ios::binary

打开文件。我还没有测试你的代码,但我建议你做一些修改:

  • 我遇到的大多数操作系统都使用约定,对于main的返回值,
    return0
    用于典型/正确的输出,
    return1
    (或非零)用于异常情况

  • 除非你真的需要,否则不要使用
    \n
    endl
    ,我不认为这里有一千种情况

  • >P>考虑重新排序<代码> 循环,因此<代码>忽略<代码>结束,考虑以下内容:

  • 无论何时从流中读取,都不要假设输出良好或流仍然有效。检查错误标志(使用bool重载或
    fp.good()
    )。仅检查
    fp.eof()
    )可能并不总是足够

  • 如果您使用的是C++11
    seekg
    即使在到达文件末尾后也应该可以正常运行,但是在早期版本中,您需要使用
    fp.clear()
    清除流错误位

  • <> L> > P >如果你没有用C++ 11编译,自动< /Cord>关键字可能不会按照你的想法去做,小心。你可能还想考虑<代码> const Auto&
如果你想四处寻找,你真的应该以
std::ios_base::binary
的形式打开文件。做了更改,但结果没有改变有多大?比可用系统内存大?不是真的。让我们说200-300 MB。但我正在尝试编写一种通过线路访问文件的有效方法。从磁盘到磁盘的操作是(以我的经验)比将文件加载到内存(如value/int/double/etc或甚至将文件映射到内存)慢。您可以尝试(一旦上述程序运行)将其与将整个文件加载到内存进行比较。