无法理解如何使用 seekg tellg 来实现以下结果

Posted

技术标签:

【中文标题】无法理解如何使用 seekg tellg 来实现以下结果【英文标题】:Cant understand how to use seekg tellg to achieve the following result 【发布时间】:2019-07-08 03:40:59 【问题描述】:

作为更大程序的一部分,我的任务是读取输入文件的每一行并将索引偏移存储到每一行。稍后给出所有索引偏移量,我希望能够直接转到文件中的那个位置并打印与该偏移量对应的行。有人可以帮我弄清楚我在以下代码中做错了什么。

    #include <iostream>
    #include <sstream> 
    #include <vector>
    #include <iterator>
    #include <stdio.h>
    #include <string.h>    

    void create_index_info(ifstream& myFile, std::unordered_map<size_t, std::pair<std::streampos, size_t>>& map_index_start_end_pos)
    
        size_t uiLength;
        size_t uiCount = 0;
        std::string line;

        while (getline(myFile, line))
                
            start_pos = myFile.tellg();
            uiLength = strlen(line.c_str());

            map_index_start_end_pos.emplace( uiCount, std::make_pair(start_pos, uiLength) );
            uiCount++;                        
        
    

    void print_index_info(ifstream& myFile, const std::unordered_map<size_t, std::pair<std::streampos, size_t>>& map_index_start_end_pos)
    
        size_t uiLength;
        for(auto it = map_index_start_end_pos.begin(); it != map_index_start_end_pos.end(); it++)
        
            auto res = it->second;

            myFile.clear();
            myFile.seekg(res.first, ios::beg);
            uiLength = res.second;

            char* buffer = (char*)malloc(uiLength * sizeof(char));
            myFile.read(buffer, uiLength);

            for(size_t uiCount = 0; uiCount < uiLength; uiCount++)
            
                std::cout<< buffer[uiCount];
            
            std::cout<<"\n";

            free(buffer);
            buffer = NULL;    
        
    

    int main()
    
        std::unordered_map<size_t, std::pair<std::streampos, size_t>> map_index_start_end_pos;
        ifstream myFile("Filename.txt");
        create_index_info(myFile, map_index_start_end_pos);
        myFile.close();

        ifstream myFile1("Filename.txt");
        print_index_info(myFile1, map_index_start_end_pos);
        myFile1.close();
        return 0;
    

输入文本文件中的数据包含以下条目:

9 10 11

8 7 5

67 34 12 45 9

20

代码的理想输出应该与输入模数相同,直到打印行的顺序(我使用的是无序映射,因此输出不需要以与输入相同的顺序打印)。但是我的代码输出了一些垃圾,主要是 \x00 形式的字符。有人可以帮我弄清楚我的代码有什么问题吗?

【问题讨论】:

为什么要以文本模式打开文件?如果以二进制模式打开,会不会更成功? 一个问题是在create_index_info 中,start_pos 指向您刚刚读取的字符串的end 每次尝试readmyFile 是否有效? 一些垃圾还是全部垃圾?请将给定输入文件的输出复制到问题中。 void main() is wrong. 【参考方案1】: 您的程序无法编译。 为什么要使用地图?为什么一个向量不够用? 为什么是getline 而不是ignoreignore 速度更快,不分配内存。

您可能正在寻找这个:

#include <iostream>
#include <vector>
#include <string>
#include <fstream>

std::istream& get_line_idx( std::istream& is, std::vector<std::streampos>& result )

  for( std::streampos pos = is.tellg(); is.ignore( std::numeric_limits<std::streamsize>::max(), '\n' ); pos = is.tellg() )
    result.push_back( pos );
  return is;


void print( std::istream& is, std::vector<std::streampos>& pos )

  for( auto curpos : pos )
  
    std::string line;
    is.seekg( curpos );
    std::getline( is, line );
    std::cout << line << std::endl;
  


int main()

  std::vector<std::streampos> result;
  
    std::ifstream is  "c:\\temp\\test.txt" ;
    if( !is )
      return -1;
    get_line_idx( is, result );
  

  
    std::ifstream is  "c:\\temp\\test.txt" ;
    if( !is )
      return -2;
    print( is, result );
  

  return 0;

【讨论】:

谢谢@ZDF,是的 void main 是一个非常糟糕的错字。我实际上需要存储与每个 streampos 对应的整行(对于我的项目要求)。在更大的方案中,该地图旨在用作我项目中的某种字典,因此矢量不适合我的目的。什么是更改 get_line_idx 中的 is.ignore 函数的安全方法,以便我可以将对应于 pos 的行(以“\n”分隔符结尾)读入 std::string ? 只需将 ignore 替换为 getline(is, line)。

以上是关于无法理解如何使用 seekg tellg 来实现以下结果的主要内容,如果未能解决你的问题,请参考以下文章

fstream::tellg() 和 ::seekg() 的问题

seekg()/seekp()与tellg()/tellp()的用法详解

“seekp”和“seekg”可以互换吗?

“seekp”和“seekg”可以互换吗?

TensorRT C++网络模型接口推理

c++中ifstream一次读取整个文件