【C++】ストリームの読み書き位置を移動する方法 (seekg, tellg)

目次

はじめに

C++のファイルストリーム (fstream) や文字列ストリーム (stringstream) を扱う際、通常は先頭から末尾へ順番に読み書きを行いますが、時には「特定のバイト位置まで一気に移動したい」「一度読んだ場所まで戻って、もう一度読み直したい」というように、読み書きする位置を自由に制御したい場合があります。

このファイルポインタ(ストリーム内の現在位置)の操作は、以下の4つのメンバ関数で行います。

  • 入力ストリーム (istream):
    • tellg(): 現在の読み取り位置 (get position) を取得する。
    • seekg(): 読み取り位置 (seek get) を移動する。
  • 出力ストリーム (ostream):
    • tellp(): 現在の書き込み位置 (put position) を取得する。
    • seekp(): 書き込み位置 (seek put) を移動する。

この記事では、これらの関数を使って、ストリーム内の任意の位置にアクセスする方法を解説します。


1. 入力ストリームの位置を操作する (tellg, seekg)

このコードは、文字列ストリームから最初の単語を読み取った後、tellg でその位置を記録し、次の単語を読み飛ばした後、seekg で記録した位置に戻って、2番目の単語を読み直します。

サンプルコード

#include <iostream>
#include <sstream> // istringstream
#include <string>

using namespace std;

int main() {
    istringstream iss("One Two Three");
    
    string word1, word2, word3;
    
    // 最初の単語 "One" を読み込む
    iss >> word1;
    
    // 1. tellg()で現在の読み取り位置を取得
    streampos read_position = iss.tellg();
    cout << "「One」を読んだ後の位置: " << read_position << endl;

    // 2番目の単語 "Two" を読み飛ばす
    iss >> word2;
    
    // 2. seekg()で、記録した位置に戻る
    iss.seekg(read_position);
    
    // 3. 再び読み込むと、2番目の単語 "Two" が読み取れる
    iss >> word3;
    
    cout << "読み直した単語: " << word3 << endl;

    return 0;
}

2. 出力ストリームの位置を操作する (tellp, seekp)

このコードは、文字列ストリームに文字列を書き込んだ後、seekp を使って先頭に戻り、内容の一部を上書きします。

サンプルコード

#include <iostream>
#include <sstream> // ostringstream
#include <string>

using namespace std;

int main() {
    ostringstream oss;
    
    oss << "Hello, world!";
    
    cout << "書き込み前: " << oss.str() << endl;

    // 1. seekp()で、書き込み位置を先頭から7バイト目に移動
    oss.seekp(7);
    
    // 2. その位置から "C++" を書き込む
    oss << "C++";
    
    cout << "書き込み後: " << oss.str() << endl;

    return 0;
}

seek関数の基準位置

seekgseekp は、移動の基準となる位置を指定できます。 stream.seekg(オフセット, 基準位置);

  • ios_base::beg: ストリームの先頭(begin)を基準とする。(デフォルト)
  • ios_base::cur: 現在位置(current)を基準とする。
  • ios_base::end: ストリームの末尾(end)を基準とする。

例: ifs.seekg(-10, ios_base::end); // 末尾から10バイト前に移動


まとめ

今回は、C++のストリームにおける読み書き位置の制御方法を解説しました。

操作入力 (get)出力 (put)
位置の取得tellg()tellp()
位置の移動seekg()seekp()

Google スプレッドシートにエクスポート

これらの関数は、バイナリファイルを直接操作して特定のデータ構造を読み書きしたり、既存のファイルの一部を上書き修正したりといった、高度なファイル操作を行う上で不可欠なツールです。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次