Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Rozdział 35 - pozycja odczytu

Ostatnio zmodyfikowano 2021-09-06 16:59
Autor Wiadomość
Barubak
Temat założony przez niniejszego użytkownika
Rozdział 35 - pozycja odczytu
» 2021-09-06 13:10:31
Witam,
Mam problem z zadaniem domowym z tego rozdziału. Program działa ale nie jestem w stanie ustawić odczytu co 3 znak. Zrobiłem test na tak "zredukowanym" kodzie:
C/C++
#include <iostream>
#include <fstream>

using namespace std;

int main()
{
   
ifstream plik;
   
plik.open( "c:\\test2.txt" );
   
   
if( !plik.good() )
   
{
       
cout << "Blad odczytu";
       
return 0;
   
}
   
int NrZnaku = 1;
   
char znak;
   
int current = 0;
   
   
plik >> znak;
   
   
cout << "Znak nr " << NrZnaku << " to: " << znak << endl;
   
   
current = plik.tellg();
   
cout << "current = " << current << endl;
   
   
return 0;
}

Wstawiłem zmienną "current" dla informacji o pozycji odczytu. Pierwsza linijka tekstu w pliku tekstowym to "1234567890112dhjqwertyuiop", konsola zwraca mi:
"Znak nr 1 to: 1
current = 3"

Nie rozumiem dlaczego current nie przyjmuje wartości 1 skoro zostaje wczytany tylko jeden znak z pozycji 0.

Zaczynam naukę od zera więc byłbym wdzięczny za łopatologiczne wyjaśnienie ;)

Z góry dziękuję za odpowiedź.
P-178926
DejaVu
» 2021-09-06 13:17:57
https://cpp0x.pl/kursy/Kurs-C++/Poziom-4/Poruszanie-sie-po-pliku-w-trybie-do-odczytu/476

Poczytaj o metodzie seekg. W Twoim kodzie w ogóle tego nie masz.
C/C++
plik.seekg( 3, std::ios::cur );
P-178927
Barubak
Temat założony przez niniejszego użytkownika
» 2021-09-06 13:32:31
Dzięki za szybką odpowiedź. Tak jak pisałem ściąłem kod bo problem dla mnie jest zrozumienie jak pozycja odczytu zmienia się po wczytaniu plik>>znak;

Pełen kod to
C/C++
#include <iostream>
#include <fstream>

using namespace std;

int main()
{
   
ifstream plik;
   
plik.open( "c:\\test2.txt" );
   
   
if( !plik.good() )
   
{
       
cout << "Blad odczytu";
       
return 0;
   
}
   
int NrZnaku = 1;
   
char znak;
   
int current = 0;
   
plik >> znak;
   
cout << "Znak nr " << NrZnaku << " to: " << znak << endl;
   
while( true )
   
{
       
current = plik.tellg();
       
cout << "current = " << current << endl;
       
plik.seekg( plik.tellg() + 2 );
       
plik >> znak;
       
       
if( !plik.fail() )
       
{
           
           
NrZnaku++;
           
cout << "Znak nr " << NrZnaku << " to: " << znak << endl;
       
}
       
else
        if
( plik.eof() )
           
 break;
       
   
}
   
return 0;
}
Dla wspomnianej linijki tekstu odpowiedź programu to:
"Znak nr 1 to: 1
current = 3
Znak nr 2 to: 6
current = 8
....
"
Z tego jak zrozumiałem lekcję nr 35 napisany program powinien wczytać znak na pozycji 0, wypisać go po czym wejść w pętlę i wypisać pozycję, która nie wiem dlaczego jest wypisywana jako 3 zamiast 1? Potem problem się powiela bo program czyta co piąty znak...
P-178928
DejaVu
» 2021-09-06 14:04:24
seekg źle używasz (nie podajesz drugiego argumentu).
P-178929
Barubak
Temat założony przez niniejszego użytkownika
» 2021-09-06 14:37:20
Sugerowałem się tym tekstem z kursu:
"Warto również w tym miejscu wspomnieć, że metodę tellg można wykorzystać przy określaniu pozycji odczytu danych z pliku:
C/C++
plik.seekg( 8, ios::cur );
//Poniższy zapis jest równoważny do powyższego:
plik.seekg( plik.tellg() + 8 );"

Wcześniej zrobiłem nawet tak jak pisałeś czyli zamiast "plik.seekg( plik.tellg() + 2 );" miałem "plik.seekg(2,ios::cur); ale program też nie działa poprawnie - czyta co czwarty znak...
P-178930
DejaVu
» 2021-09-06 14:44:16
Znak nr 1 to: [
current = 1
Znak nr 2 to: r
current = 4
Znak nr 3 to: o
current = 7
Znak nr 4 to: b
current = 12
Znak nr 5 to: n
current = 15

C/C++
cout << "current = " << current << endl;
plik.seekg( 2, std::ios::cur ); //ta linijka działa
plik >> znak;

/edit:
Widzę, że trochę słabo działa ten cały seekg jeżeli nowe linie występują w pliku...
P-178931
Barubak
Temat założony przez niniejszego użytkownika
» 2021-09-06 16:59:18
Witam,

Rzeczywiście - jak zostawiłem tylko jedną linijkę w pliku to program zaczyna działać poprawnie, bez znaczenia czy używam "plik.seekg( plik.tellg() + 2 );" czy też "plik.seekg(2,ios::cur)". Dziękuję za pomoc:)
P-178933
« 1 »
  Strona 1 z 1