std::basic_...buf::seekoff(3)
π NAME π
std::basic_stringbuf::seekoff β the manual literally spells it out as std::basic_stringbuf::seekoff - std::basic_stringbuf::seekoff, and this is the std::basic_...buf::seekoff(3) page from the C++ Standard Libary manual. We're talking about the protected virtual member that repositions stringbuf pointers, bestie. β¨
β¨ Synopsis β¨
Okay so the signature is protected and virtual, and it's giving default-argument realness:
protected:
virtual pos_type seekoff( off_type off,
std::ios_base::seekdir dir,
std::ios_base::openmode which =
std::ios_base::in |
std::ios_base::out );
Repositions std::basic_streambuf::gptr and/or std::basic_streambuf::pptr, if possible, to the position that corresponds to exactly off characters from beginning, end, or current position of the get and/or put area of the buffer. π«Ά
Here's the vibe check on when each pointer gets moved:
- If
whichincludesstd::ios_base::inand this buffer is open for reading (that is, if(which & std::ios_base::in) == std::ios_base::in), then repositions the read pointerstd::basic_streambuf::gptrinside the get area as described below. - If
whichincludesstd::ios_base::outand this buffer is open for writing (that is,(which & std::ios_base::out) == std::ios_base::out), then repositions the write pointerstd::basic_streambuf::pptrinside the put area as described below. - If
whichincludes bothstd::ios_base::inandstd::ios_base::outand the buffer is open for both reading and writing (that is,(which & (std::ios_base::in | std::ios_base::out)) == (std::ios_base::in | std::ios_base::out)), anddiris eitherstd::ios_base::begorstd::ios_base::end, then repositions both read and write pointers as described below. - Otherwise, this function fails. π
If gptr and/or pptr is repositioned, it is done as follows:
- The new pointer offset
newoffof typeoff_typeis determined:- a) if
dir == std::ios_base::beg, thennewoffis zero - b) if
dir == std::ios_base::cur, thennewoffis the current position of the pointer (gptr() - eback()orpptr() - pbase()) - c) if
dir == std::ios_base::end, thennewoffis the length of the entire initialized part of the buffer (if over-allocation is used, the high watermark pointer minus the beginning pointer)
- a) if
- If the pointer to be repositioned is a null pointer and
newoffwould be non-zero, this function fails. - If
newoff + off < 0(the repositioning would move the pointer to before the beginning of the buffer) or ifnewoff + offwould point past the end of the buffer (or past the last initialized character in the buffer if over-allocation is used), the function fails. - Otherwise, the pointer is assigned as if by
gptr() = eback() + newoff + offorpptr() = pbase() + newoff + off.
π Parameters π
The manual labels these Constant / Explanation, so here's the group-chat translation that keeps every constant:
offβ relative position to set the next pointer(s) to.dirβ defines base position to apply the relative offset to. It can be one of the following constants:begβ the beginning of a streamendβ the ending of a streamcurβ the current position of stream position indicator
whichβ defines whether the input sequences, the output sequence, or both are affected. It can be one or a combination of the following constants:inβ affect the input sequenceoutβ affect the output sequence
π«Ά Return value π«Ά
pos_type(newoff) on success, pos_type(off_type(-1)) on failure or if pos_type cannot represent the resulting stream position. So success gives you pos_type(newoff); failure or can't-represent gives you pos_type(off_type(-1)). No cap. π
πΈ Example πΈ
Code is sacred, so here it is exactly:
// Run this code
#include <iostream>
#include <sstream>
int main()
{
std::stringstream ss("123"); // in/out
std::cout << "put pos = " << ss.tellp()
<< " get pos = " << ss.tellg() << '\n';
// absolute positioning both pointers
ss.rdbuf()->pubseekoff(1, std::ios_base::beg); // move both 1 forward
std::cout << "put pos = " << ss.tellp()
<< " get pos = " << ss.tellg() << '\n';
// try to move both pointers 1 forward from current position
if (-1 == ss.rdbuf()->pubseekoff(1, std::ios_base::cur))
std::cout << "moving both pointers from current position failed\n";
std::cout << "put pos = " << ss.tellp()
<< " get pos = " << ss.tellg() << '\n';
// move the write pointer 1 forward, but not the read pointer
// can also be called as ss.seekp(1, std::ios_base::cur);
ss.rdbuf()->pubseekoff(1, std::ios_base::cur, std::ios_base::out);
std::cout << "put pos = " << ss.tellp()
<< " get pos = " << ss.tellg() << '\n';
ss << 'a'; // write at put position
std::cout << "Wrote 'a' at put position, the buffer is now " << ss.str() << '\n';
char ch;
ss >> ch;
std::cout << "reading at get position gives '" << ch << "'\n";
}
Output:
put pos = 0 get pos = 0
put pos = 1 get pos = 1
moving both pointers from current position failed
put pos = 1 get pos = 1
put pos = 2 get pos = 1
Wrote 'a' at put position, the buffer is now 12a
reading at get position gives '2'
π¦ Defect reports π¦
These behavior-changing defect reports were applied retroactively to previously published C++ standards. History really said "let's fix it" and we're obsessed:
- LWG 55 β applied to C++98. Behavior as published:
seekoffreturned an undefined invalid stream position on failure. Correct behavior:pos_type(off_type(-1))is returned on failure. - LWG 375 β applied to C++98. Behavior as published: static constant members of
std::ios_basewere misspecified as members ofstd::basic_ios. Correct behavior: corrected. - LWG 432 β applied to C++98. Behavior as published:
seekoffmight succeed even ifnewoff + offwould point past the last initialized character. Correct behavior:seekofffails in this case. - LWG 453 β applied to C++98. Behavior as published: repositioning null
gptr()and/or nullpptr()with a new offset of zero always failed. Correct behavior: it can succeed in this case. - LWG 563 β applied to C++98. Behavior as published: the end pointer could not be used to calculate
newoffbecause it could not be precisely controlled by the program after resolving LWG issue 432. Correct behavior: use the high watermark pointer instead.
π See also π
These are the linked besties, with every parenthetical intact:
pubseekoffβ invokesseekoff()(public member function ofstd::basic_streambuf<CharT,Traits>)seekpos[virtual] β repositions the next pointer in the input sequence, output sequence, or both using absolute addressing (virtual protected member function)seekoff[virtual] β repositions the file position, using relative addressing (virtual protected member function ofstd::basic_filebuf<CharT,Traits>)seekoff[virtual] β repositions the next pointer in the input sequence, output sequence, or both, using relative addressing (virtual protected member function ofstd::strstreambuf)
Bye bestie! This was the std::basic_...buf::seekoff(3) page from the C++ Standard Libary manual. Source/version/date: http://cppreference.com, 2024.06.10. Mwah πβ¨
π¦ where this page comes from
- nixpkgs unstable: stdman 2024.07.05
- opensuse-leap 16.0: stdman 2024.07.05-bp160.1.9 Β· MIT
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms