从文件C++中的特定位置读取
Read from a specific spot in a file C++
我在C++中有一个程序,需要返回特定单词出现的行。例如,如果我的文件看起来像这样:
the cow jumped over
the moon with the
green cheese in his mouth
我需要打印带有"with"的行。程序得到的只是文件开头的偏移量(在本例中为 24,因为"with"是文件开头的 24 个字符)。
如何打印整行"月亮与",仅偏移量?
多谢!
您可以通过单独读取每一行并记录读取前后的文件位置来执行此操作。然后,只需检查单词的偏移量是否在该行的范围内即可。
#include <iostream>
#include <fstream>
#include <string>
std::string LineFromOffset(
const std::string &filename,
std::istream::pos_type targetIndex)
{
std::ifstream input(filename);
// Save the start position of the first line. Should be zero of course.
std::istream::pos_type lineStartIndex = input.tellg();
while(false == input.eof())
{
std::string line;
std::getline(input, line);
// Get the end position of the line
std::istream::pos_type lineEndIndex = input.tellg();
// If the index of the word we're looking for in the bounds of the
// line, return it
if(targetIndex >= lineStartIndex && targetIndex < lineEndIndex)
{
return line;
}
// The end of this line is the start of the next one. Set it
lineStartIndex = lineEndIndex;
}
// Need a better way to indicate failure
return "";
}
void PrintLineTest()
{
std::string str = LineFromOffset("test.txt", 24);
std::cout << str;
}
一个好的解决方案是从头到所需位置读取文件(由@Chet辛普森回答)。如果你想要优化(例如,非常大的文件,位于中间的某个地方,典型的行相当短),你可以向后读取文件。但是,这仅适用于以二进制模式打开的文件(类 Unix 平台上的任何文件;在 Windows 上使用 ios_base::binary
参数打开文件)。
算法如下:
- 在文件中返回几个字节
- 读取几个字节
- 如果那里有生产线末端,其余的都很容易
- 否则,请重复
代码(在Windows上测试):
std::string GetSurroundingLine(std::istream& f, std::istream::pos_type start_pos)
{
std::istream::pos_type prev_pos = start_pos;
std::istream::pos_type pos;
char buffer[40]; // typical line length, so typical iteration count is 1
std::istream::pos_type size = sizeof(buffer);
// Look for the beginning of the line that includes the given position
while (true)
{
// Move back 40 bytes from prev_pos
if (prev_pos < size)
pos = 0;
else
pos = prev_pos - size;
f.seekg(pos);
// Read 40 bytes
f.read(buffer, prev_pos - pos);
if (!f)
throw;
// Look for a newline byte, which terminates previous line
int eol_pos;
for (eol_pos = sizeof(buffer) - 1; eol_pos >= 0; --eol_pos)
if (buffer[eol_pos] == 'n')
break;
// If found newline or got to beginning of file - done looking
if (eol_pos >= 0 || pos == (std::istream::pos_type)0)
{
pos += eol_pos + 1;
break;
}
}
// Position the read pointer
f.seekg(pos);
// Read the line
std::string s;
std::getline(f, s, 'n');
return s;
}
编辑:在类似Windows的平台上,行尾用rn
标记,由于您必须使用二进制模式,因此输出字符串将包含额外的字符r
(除非文件末尾没有行尾),您可以将其丢弃。
每个操作都有函数
fopen
- 打开文件
fseek
- 将文件查找到所需的偏移量
fread
- 读取所需的字节数
fclose
- 关闭文件
相关文章:
- 将值指定给向量(2D)的向量中的某个位置
- 使用Unreal C++获取VR耳机的世界位置/方向
- 写入位置0x0000000C时发生访问冲突
- 如何将两个不同矢量的同一位置的两个元素组合在一起
- GL_SHADERSTORAGE_BUFFER位置是否与其他着色器位置冲突
- 如何使用cudaMallocManaged在指针位置初始化对象?(C++)
- 无法获取webot::PositionSensor对象中位置传感器的值
- 非常量变量只读位置的赋值
- 如何定义更改car类中car位置的方法
- 使用迭代器时如何访问对象在向量中的位置?
- 更改.cpp程序的输入文件中数据的位置会意外更改输出
- 求最大元素位置的分治算法
- 你好。。。id_public变量不应该给出结果为 81 和 86 吗?为什么它为两个派生类占用不同的内存位置?
- 是与初始类同一内存位置的重新定位类
- 如何在使用网格布局时重叠qwidgets,并将重叠的widget定位在距离窗口边界特定距离的位置
- 我不知道如何定位最高随机数的位置
- 如何在MFC上设置窗口位置以将其定位到屏幕顶部
- 将QGraphicsSvgItem的中心定位在一个位置上。
- 如何定位WinRT异步方法调用中出现错误的位置
- 重定位表项在平面二进制文件中的存储位置