wczytywanie pliku do końca

wczytywanie pliku do końca
  • Rejestracja: dni
  • Ostatnio: dni
0

Witam.
Gdy próbuje odczytać coś z pliku to ostatni odczyt podwójny:

Kopiuj
fstream f("plik.bin",ios:binary|ios:in);
while(!f.eof())
{
f.read(...);
}
f.close();

Gdy do pętli dodam jeszcze tego if'a to wszystko działa.

Kopiuj
if(!f.eof())
break;

Dlaczego tak jest?

mad_penguin
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Rzeszów
1

Flaga eof jest ustawiana dopiero jak spróbujesz odczytać dane poza granicą pliku, nie wystarczy tylko dojść do jego końca. Tak więc w przypadku pliku mającego 3 bajty pętla

Kopiuj
while(!f.eof())
{
f.read(bufor, 1);
}

wykona się 4 razy.
Bez całego kodu więcej nie jestem w stanie stwierdzić jak to wygląda w Twoim przypadku.

kq
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Szczecin
0

http://en.cppreference.com/w/cpp/io/basic_ios/eof

This function only reports the stream state as set by the most recent I/O operation; it does not examine the associated data source. For example, if the most recent I/O was a get(), which returned the last byte of a file, eof() returns false. The next get() fails to read anything and sets the eofbit. Only then eof() returns true.

nalik
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 1039
  • Rejestracja: dni
  • Ostatnio: dni
0

To jak zrobić żeby nie było podwójnego odczytu?
Nie chce zapisywać dodatkowej zmiennej w pliku.

Kopiuj
class test {
... 
} 

fstream f("plik.bin",ios:binary|ios:in);
while(!f.eof())
{
test t;
f.read((char*)&t, sizeof(t)) ;
}
f.close();

kq
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Szczecin
0

To powinno działać:

Kopiuj
test t;
while(f.read((char*)&t, sizeof(t))) {
    foo(t);
}
  • Rejestracja: dni
  • Ostatnio: dni
0

Dzięki za pomoc.
@nalik
Funkcje z tego artykułu wydają mi się bardzo trudne do zrozumienia(dużo nawiasów jest).

WY
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 134
0

Piszę z telefonu także, nie mam jak wrzucić kodu, ale zrób pętlę while(f >> zmienna) i powinno załatwić sprawę :)

KM
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 473
0

@nalik:

Wytłumaczysz mi, czemu to działa?

Kopiuj
auto ss = std::ostringstream{};
ss << in.rdbuf();
auto s = ss.str();

Czego nie rozumiem: Ten kod zdaje się zakładać, że cały plik jest w buforze. I dlatego robi ss << in.rdbuf();.

Czemu można tak zakładać? Skąd wiadomo, że wczytany zostanie cały plik, a nie tylko akurat ten fragment, który jest zbufrowowany?

Skąd w ogóle wiadomo, że wczytywanie jest tutaj buforowane?

nalik
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 1039
1

Buffor sam będzie wczytywwał dane. Bo to std::basic_filebuf otwiera plik. Ale czy to jest wydajne to inna sprawa patrząc ile kodu tam jest.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.