从文件C ++中的特定位置读取 [英] Read from a specific spot in a file C++

查看:171
本文介绍了从文件C ++中的特定位置读取的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个C ++程序,需要返回一个特定词出现的行。例如,如果我的文件是这样:

I have a program in C++ that needs to return a line that a specific word appears in. For instance, if my file looks like this:

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

,我需要打印有with的行。所有的程序获取是从文件的开头的偏移量(在这种情况下为24,因为with是从文件开头的24个字符)。

and I need to print the line that has "with". All the program gets is the offset from the beginning of the file (in this case 24, since "with" is 24 characters from the beginning of the file).

我打印整行月亮与,只是偏移?

How do I print the whole line "the moon with the", with just the offset?

非常感谢!

推荐答案

一个很好的解决方案是从头开始直到所需的位置读取文件(由@Chet Simpson回答)。如果您想要优化(例如,非常大的文件,位于中间的某个地方,典型的行很短),您可以向后读取文件。但是,这只适用于以二进制模式打开的文件(在类Unix平台上的任何文件;在Windows上使用 ios_base :: binary 参数打开文件)。

A good solution is reading the file from the beginning until the desired position (answer by @Chet Simpson). If you want optimization (e.g. very large file, position somewhere in the middle, typical lines rather short), you can read the file backwards. However, this only works with files opened in binary mode (any file on unix-like platforms; open the file with ios_base::binary parameter on Windows).

算法如下:


  • 返回文件中的几个字节

  • 读取几个字节

  • 如果有行尾,其余的很容易

  • 重复

  • Go back a few bytes in file
  • Read the few bytes
  • If there is an end-of-line there, the rest is easy
  • Otherwise, repeat

代码(在Windows上测试):

Code (tested on 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\\\
,因为您必须使用二进制模式,输出字符串将包含额外的字符 \r (除非在文件结尾处没有行尾),你可以抛弃它。

On Windows-like platforms, where end-of-line is marked by \r\n, since you have to use binary mode, the output string will contain the extra character \r (unless there is no end-of-line at end-of-file), which you can throw away.

这篇关于从文件C ++中的特定位置读取的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆