C++ifstream读取偏移范围

C++ ifstream read offset range

本文关键字:范围 读取 C++ifstream      更新时间:2023-10-16

我处理一个文件,在这个文件内容中:"hello_READHERE_guys"。如何只阅读"阅读"位置?

我尝试了这段代码并失败了:

std::ifstream is("test.txt");
if (is.good())
{
    is.seekg(5, ios::end); // step from end "_guys"
    is.seekg(6, ios::beg); // step from start "hello_"
    std::string data;
    while (is >> data) {}
    std::cout << data << std::endl; // output "READHERE_guys" fail.
}

seekg 函数仅设置要从输入流中提取的下一个字符的位置。它不能设置停止的"限制"。所以下面的行:

is.seekg(5, ios::end); // step from end "_guys"

不正确。将 seekg 与 ios::end 一起使用不会设置限制。

但是,您的其他用法是正确的。如果你只想读取一个特定的数据块,并且如果你确切地知道这个数据块的大小(字符串"READHERE"的精确大小),你可以使用 istream::read 函数来读取它:

std::ifstream is("test.txt");
if (is.good())
{
    is.seekg(5, ios::end); // step from end "_guys"

    std::string data(sizeof("READHERE"), ''); // Initialize a string of the appropriate length.
    is.read(&data[0], sizeof("READHERE")); // Read the word and store it into the string.
    std::cout << data << std::endl; // output "READHERE".
}

当您第一次调用seekg时,它会在文件中的指定位置设置一个"光标"。然后在你第二次调用seekg后,它会将该"curson"设置为另一个位置(现在在"head_"之后),但它不关心之前的调用,所以它不会像你想象的那样阅读。

一种解决方案是作为 folows:

std::string data;
is.ignore(std::numeric_limits<std::streamsize>::max(), '_');
std::getline(is, data, '_');

std::ifstream::ignore用于跳过所有内容,直到并包括第一次出现"_"。现在std::getline从该文件中读取所有内容(当然在跳过部分之后),直到遇到作为第三个参数('_')提供的字符分隔符,因此它将准确读取您想要的内容。