C++ ifstream read offset range

I work an file, in this file content: "hello_READHERE_guys". How to read "READHERE" position only?

I trying this code and fail:

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.
}

Upvotes: 2

Views: 5268

Answers (2)

Aracthor
Aracthor

Reputation: 5907

The seekg function does only set the position of the next character to be extracted from the input stream. It cannot set a "limit" to stop. So the following line:

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

Is incorrect. A use of seekg with ios::end won't set a limit.

Your other use is correct however. If you want to read just a specific block of data, and if you know precisely the size of this block of data (the precise size of the string "READHERE"), you can use the istream::read function in order to read it:

std::ifstream is("test.txt");

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


    std::string data(sizeof("READHERE"), '\0'); // 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".
}

Upvotes: 3

Yuriy Ivaskevych
Yuriy Ivaskevych

Reputation: 966

When you first call seekg it sets a 'cursor' in file in specified position. Then after you call seekg second time it sets that 'curson' in another position (after 'head_' now) but it doesn't care about previous call so it wouldn't read as you suppose.

One solution is as folows:

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

std::ifstream::ignore is used to skip everything until and including first occurence of '_'. Now std::getline reads everything from that file (after skipped part of course) till it encounters characher-delimiter that is provided as third argument ('_') so it would read exactly what you want.

Upvotes: 1

Related Questions