戻る

C++によるバイナリファイル操作

Dec 20, 2019

c++11以降のバイナリファイル操作についてまとめたい. やり方が皆バラバラでどういう方法を取ればいいのか骨となるものがなければ混乱する.

tellp

std::basic_ostream::tellp

if fail () == true, it returns pos_type(-1). Otherwise, returns rdbuf()->pubseeekoff(0, std::iosbase::cur, std::ios_base::out)

引数なし, 返却型はpos_type


#include <iostream>
#include <sstream>
int main()
{
    std::ostringstream s;
    std::cout << s.tellp() << '\n';
    s << 'h';
    std::cout << s.tellp() << '\n';
    s << "ello, world ";
    std::cout << s.tellp() << '\n';
    s << 3.14 << '\n';
    std::cout << s.tellp() << '\n' << s.str();
}

出力:


0
1
13
18
hello, world 3.14

seekp

basic_ostream& seekp( pos_type pos ); (1)

basic_ostream& seekp( off_type off, std::ios_base::seekdir dir); (2)

(1) sets the output position indicator to absolute (relative to the beginning of the file) value pos by calling rdbuf()->pubseekpos(pos, std::ios_base::out) . If the call returns (pos_type)-1, executes setstate(failbit) .

(2) sets the output position indicator to offset off relative to dir by calling rdbuf()->pubseekoff(off, dir, std::ios_base::out) . If the call returns (pos_type)-1, executes setstate(failbit). (since C++14)

引数

pos - absolute position to set the output position indicator to.

off - relative position to set the output position indicator to.

dir - defines base position to apply the relative offset to. It can be one of the following constants. beg : the beginning of a stream, end : the ending of a stream, cur : the current position of stream position indicator

返却型

*this

例外

(1) May throw std::ios_base::failure in case of failure, if exceptions() & failbit != 0

(2) Same as (1)


#include <sstream>
#include <iostream>

int main()
{
  std::ostringstream os("hello, world");
  os.seekp(7);
  os << 'W';
  os.seekp(0, std::ios_base::end);
  os << '!';
  os.seekp(0);
  os << 'H';
  std::cout << os.str() << '\n';
}

出力:


Hello, World!

tellg

std::basic_istream::tellg, pos_type tells(); return input position indicator of the current associated streambuf object. if fail() == true, returns pos_type(-1). Otherwise, returns rdbuf()->pubseekoff(0, std::ios_base::cur, std::ios_base::in).

引数なし, 返却成功時はpointerの現在位置, 失敗時はpos_type(-1)

failure if an error occurred (the error state flag is not goodbit) and exceptions() is set to throw for that state. If an internal operation throws an exception, it is caught and badbit is set. If exceptions() is set for badbit, the exception is rethrown.


#include <iostream>
#include <string>
#include <sstream>

int main()
{
  std::string str = "Hello, world";
  std::istringstream in(str);
  std::string word;
  in >> word;
  std::cout << "After reading the word \"" << word
    << "\" tellg() returns " << in.tellg() << '\n';

出力:


After reading the word "Hello," tellg() returns 6

seekg

std::basic_istream::seekg

(1) basic_istream& seekg(pos_type pos);

(2) basic_istream& seekg(off_type off, std::ios_base::seekdir dir);

Sets input position indicator of the current associated streambuf object. In case of failure, calls setstate(std::ios_base::failbit) . Before doing anything els, seekg clears eofbit. (since C++11)

(1) sets the input position indicator to absolute (relative to the beginnning of the file) value pos. Specifically, executes rdbuf()->pubseekpos(pos, std::ios_base::in) .

(2) sets the input position indicator to position off, relative to position, defined by dir. Specifically, executes rdbuf()->pubseekoff(off, dir, std::ios_base::in) .

Parameters

pos - absolute position to set the input position indicator to.

off - relative position to set the input position indicator to.

dir - defines base position to apply the relative offset to. It can be one of the following constants: beg : the beginning of a stream. end : the ending of a stream. our : the current position of stream position indicator.

Return value is *this

failure if an error occurred (the error state flag is not goodbit) and exceptions() is set to throw for that state. If an internal operation throws an exception, it is caught and badbit is set. If exceptions() is set for badbit, the exception is rethrown.

Example


#include <iostream>
#include <string>
#include <sstream>

int main() 
{
  std::string str = "Hello, world";
  std::istringstream in(str);
  std::string word1, word2;

  in >> word1;
  in.seekg(0); // rewind
  in >> word2;

  std::cout << "word1 = " << word1 << '\n'
            << "word2 = " << word2 << '\n';
}

Output:


word1 = Hello,
word2 = Hello,

pubseekoff

std::streambuf::pubseekoff, public member function

streampos pubseekoff (streamoff off, ios_base::seekdir way, ios_base::opermode which = ios_base::in | ios_base::out);

Set internal position pointer to relative position. Call the protected virtual member seekoff with the same arguments off, way and which. Member seek of does nothing in streambuf but derived classes shall override this behavior to after the internal pointers appropriately: both filebuf and stringbuf override this virtual member function to set the internalpointer specified by which to a position offset off relative to the direction specified by way.

Parameters

off - Offset value, relative to the way parameter. streamoff is an offset type (generally, a signed integral type).

way - Object of type ios_base::seekdir. It may take any of the following constant values: ios_base::beg : beginning of the stream buffer. ios_base::cur : current position in the stream buffer. ios_base::end end of the stream buffer.

which - Generally used to determine the position on which of the controlled sequences shall be modified: the input sequence, the outputsequence, or both. It is an object of type ios_base::openmode that, for this function, may take any combination of the following significant constant values: ios_base::in : modify current position in controlled input sequence. ios_base::out : Modify current position in controlled output sequence.

Return Value

The new position of the modified position pointer. The default definition in streeammbuf always returns -1. streampos is a positioning type that can be converted to/from integral types (an fpos type).

Example


#include <iostream>
#include <fstream>
int main () {
  std::fstream filestr ("test.txt");
  if (filestr) {
    std::streambuf* pbuf = filestr.rdbuf();
    long size = pbuf->pubseekoff(0,filestr.end);
    std::cout << "The file size is " << size << " characters.\n";
    filestr.close();
  }
  return 0;
}

pubseekpos

std::streambuf::pubseekpos, public member function

streampos pobseekpos(streampos pos, ios_base::openmode which = ios_base::in | ios_base::out);

Set internal position pointer to absolute position. Calls the protected virtual member seekpos with the same arguments pos and which. Member seekpos does nothing in streambuf, but derived classes shall override this behavior to alter the internal pointers appropriately: both filebuf and stringbuf override this virtual member function to set the internal pointer specified by which to the absolute position pos.

Parameters

pos - Same as pubseekoff

which - Same as pubseekoff

Return Value

Same as pubseekoff

Exmaple

Following example reads and prints 10 characters of a file starting at position 10 (character 11th to 20th).


// change position with pubseekpos
#include <iostream> // std::cout, std::streambuf
#include <fstream> // std::fstream

int main() {
  std::fstream filestr("test.txt");
  if (filestr) {
    std::streambuf* pbuf = filestr.rdbuf();
    long size = pbuf->pubseekoff(0,filestr.end);  // get size
    if (size>20) {
      char buffer[11];
      // change position to 10
      pbuf->pubseekpos(10);
      // read 10 characters
      pbuf->sgetn (buffer,10);
      // append null character to string
      buffer[10]=0;
      std::cout << buffer << '\n';
    }
    filestr.close();
  }
  return 0;
}

test.txt:


abcdefghijklmnopqrstuvwxyz

Output:


klmnopqrst

sgetn

std::streambuf::sgetn, public member function

streamsize sgetn (char* s, streamsize n); Get sequence of characters Calls the protected virtual member xgetn with the same arguments s and n. The default definition of xgetn in streambuf retrieves characters from the controlled input sequence and stores them in the array pointed by s, until either n characters have been extracted or the end of the sequence is reached.

Parameters

s - Pointer to an array where the character sequence is copied.

n - Maximum number of characters to be retrieved. This shall be a non-negative value. streamsize is a signed integral type.

Return Value

The number of characters copied. streamsize is a signed integral type.

Example

Following example reads an entire file into a buffer using its stream buffer, and is then written to the standard output.


// read a file into buffer - sgetn() example
#include <iostream>  // std::cout, std::streambuf, std::streamsize
#include <fstream>  // std::ifstream

int main() {
  char* contents;
  std::ifstream istr ("test.txt");
  if (istr) {
    std::streambuf* pbuf = istr.rdbuf();
    std::streamsize size = pbuf->pubseekoff(0,istr.end);
    pbuf->pubseekoff(0,istr.beg);  // rewind
    contents  = new char [size];
    pbuf->sgetn (contents, size);
    istr.close();
    std::cout.write(contents,size);
    return 0;
  }
}

test.txt:


TextMate may be the latest craze for developing Ruby on Rails applications,
but Vim is forever.

Output:


TextMate may be the latest craze for developing Ruby on Rails applications,
but Vim is forever.

rdbuf

std::ios::rdbuf, public member function

get (1) streambuf* rdbuf() const;

set (2) streambuf* rdbuf(streambuf* sb);

Get/set stream buffer. The first form (1) returns a pointer to the stream buffer object currently associated with the stream. The second form (2) also sets the object pointed by sb as the stream buffer associated with the streeam and clears the error state flags. If sb is a null pointer, the function automatically sets the badbit error state flags (which may throw an exception if member exceptions has been passed badbit). Some derived stream classes (such as stringstram and fstream) maintain their own internal stream buffer, to which they are associated on construction. Calling this functino to change the associated stream buffer shall have no effect on that internal stream buffer: the stream will have an associated stream buffer which is different from its internal stream buffer (although input/output operations on streams always use the associated stream buffer, as returned by this member function).

Parameters

sb - Pointer to a streambuf object.

Return Value

A pointer to the stream buffer object associated with the stream before the call.

Example

Following example uses both function forms: first to get a pointer to a file's streambuf object and then to assign it to cout.


// redirecting cout's output thrrough its stream buffer
#include <iostream>     // std::streambuf, std::cout
#include <fstream>      // std::ofstream

int main () {
  std::streambuf *psbuf, *backup;
  std::ofstream filestr;
  filestr.open ("test.txt");

  backup = std::cout.rdbuf();     // back up cout's streambuf

  psbuf = filestr.rdbuf();        // get file's streambuf
  std::cout.rdbuf(psbuf);         // assign streambuf to cout

  std::cout << "This is written to the file";

  std::cout.rdbuf(backup);        // restore cout's original streambuf

  filestr.close();

  return 0;
}