std::istream::seekg în C++

Mută poziția de citire în flux (seekg) și arată poziția curentă (tellg).

Sintaxă
std::istream& seekg(std::streampos pozitie);
std::istream& seekg(std::streamoff deplasare, std::ios::seekdir fata_de);
std::streampos tellg();

Ce face std::istream::seekg

Un flux de citire ține minte poziția de la care va citi următorul octet. tellg() returnează această poziție, iar seekg o mută: la o poziție absolută (seekg(0) = început) sau relativ la std::ios::beg, std::ios::cur ori std::ios::end.

Un truc des folosit: seekg(0, std::ios::end) urmat de tellg() dă mărimea fișierului în octeți. Pentru scriere există perechea seekp/tellp.

Dacă citirea a ajuns deja la final (eof), seekg nu funcționează până nu apelezi clear().

Parametri

Parametru Descriere
pozitie Poziția absolută, în octeți de la început.
deplasare, fata_de Câți octeți să se mute, față de std::ios::beg, cur sau end.

Ce returnează

seekg returnează fluxul. tellg returnează poziția sau -1 dacă fluxul este în stare de eroare.

Exemple

Exemplul 1: Mărimea unui fișier

Textul are 18 litere, dar „ș” și „ț” au câte 2 octeți, deci fișierul are 20 de octeți.

#include <fstream>
#include <iostream>

int main() {
    std::ofstream("text.txt") << "Piatra Neamț, Iași";

    std::ifstream in("text.txt", std::ios::binary);
    in.seekg(0, std::ios::end);
    std::cout << "Mărime: " << in.tellg() << " octeți\n";
}

Rezultat

Mărime: 20 octeți

Exemplul 2: Citirea de două ori a aceluiași fișier

#include <algorithm>
#include <fstream>
#include <iostream>

int main() {
    std::ofstream("valori.txt") << "4 8 15 16 23 42";

    std::ifstream in("valori.txt");
    int x, suma = 0, maxim = 0;
    while (in >> x) suma += x;

    in.clear();   // ștergem starea eof
    in.seekg(0);  // înapoi la început
    while (in >> x) maxim = std::max(maxim, x);

    std::cout << "Suma: " << suma << ", maximul: " << maxim << '\n';
}

Rezultat

Suma: 108, maximul: 42

Exemplul 3: Unde am rămas cu citirea

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

int main() {
    std::istringstream in("Ana Maria Popescu");
    std::string cuvant;
    in >> cuvant;
    std::cout << "După \"" << cuvant << "\" poziția este " << in.tellg() << '\n';
    in.seekg(4);
    in >> cuvant;
    std::cout << "De la poziția 4: " << cuvant << '\n';
}

Rezultat

După "Ana" poziția este 3
De la poziția 4: Maria

Greșeli frecvente

  • Apelezi seekg(0) după ce bucla de citire a ajuns la final, fără clear(): fluxul rămâne în eroare și a doua citire nu găsește nimic.
  • Folosești tellg pe un fișier deschis în mod text pe Windows și te aștepți ca numerele să corespundă caracterelor: din cauza lui \r\n, pot diferi. Deschide în std::ios::binary pentru poziții exacte.

Comenzi înrudite

  • std::istream::read: Citește sau scrie un număr exact de octeți: read și write, pentru fișiere binare.
  • std::fstream: Flux de fișier care poate și citi, și scrie în același fișier.
  • std::istream::eof: Verifică starea unui flux: eof (sfârșitul datelor) și fail (citire eșuată).