无法理解如何使用 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。
每次尝试read
后myFile
是否有效?
一些垃圾还是全部垃圾?请将给定输入文件的输出复制到问题中。
void main()
is wrong.
【参考方案1】:
您的程序无法编译。
为什么要使用地图?为什么一个向量不够用?
为什么是getline
而不是ignore
? ignore
速度更快,不分配内存。
您可能正在寻找这个:
#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() 的问题