从文件下的特定地点阅读++(Read from a specific spot in a file

2019-09-18 00:12发布

我有在C ++中,需要返回一个特定的词出现在一行的程序例如,如果我的文件看起来像这样:

the cow jumped over
the moon with the
green cheese in his mouth

我需要打印有“与”行。 所有程序得到的是在从文件开始的偏移(在这种情况下24,因为“与”从文件的开头24个字符)。

如何打印整行“月亮的”,只有偏移?

非常感谢!

Answer 1:

一个好的解决办法是阅读从开始的文件,直到所需的位置(由@Chet辛普森的答案)。 如果你想优化(如非常大的文件,位置在中间某个地方,典型的线比较短),你可以向后读取文件。 然而,这个文件只能在二进制模式打开(在类UNIX平台的任何文件,打开该文件ios_base::binary在Windows参数)。

该算法去如下:

  • 返回文件的几个字节
  • 阅读几个字节
  • 如果有一个最终的线在那里,其余的是容易
  • 否则,重复

代码(在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类平台,在这里结束的线被标注为\r\n ,因为你必须使用二进制模式,输出字符串将包含额外的字符\r (除非没有结束行在结束文件),你可以扔掉。



Answer 2:

您可以通过单独读取每一行之前和之后读记录文件位置做到这一点。 然后,它只是一个简单的检查,看看是否在词的偏移线的范围内。

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


Answer 3:

有每个操作的fopen的功能 - 打开文件

FSEEK - 寻找文件所需的偏移量

FREAD - 读你想要的字节量

FCLOSE - 关闭文件



文章来源: Read from a specific spot in a file C++