2011-07-20 19 views
22

Używam standardowego iostream, aby uzyskać pewne dane wejściowe z pliku, i jestem zdezorientowany o unget() w stosunku do putback(character). Z dokumentacji wydaje mi się, że te funkcje są identyczne, gdzie unget() wspomina tylko postać, więc jestem zdenerwowana. Zawsze używałem putback(character), ale character jest zawsze ostatnią postacią czytającą i zastanawiałem się nad zmianą na unget(). Czy putback(character) zawsze jest identyczne z unget(), jeśli character jest zawsze ostatnim znakiem do odczytu?Różnica między putback() i unget()

Odpowiedz

16

Nie można kłamać z numerem unget(). "Ungets" to ostatnia postać. Możesz leżeć z putback(c). Możesz "odrzucić" jakiś znak, inny niż ostatni odczytany znak. Czasami przydatne może być przywrócenie postaci innej niż ostatnia.

Ponadto, jeśli bazowy bufor odczytu rzeczywiście ma zdolność buforowania, można "odrzucić" więcej niż jeden znak. Myślę, że ungetc() jest ograniczony do jednego znaku.

Edytuj
Nie. Wygląda na to, że unget() może sięgać aż do putback().

+0

Nie chodzi o to, że narzekam na twoją całkowicie rozsądną odpowiedź, ale nie sądzę, że to faktycznie odpowiada na pytanie. Jeśli zastąpię wszystkie moje wywołania 'putback (znak)' (gdzie 'znak' jest gwarantowany jako ostatni odczytany znak) z' unget() ', czy zdefiniowane zachowanie jest identyczne? – Puppy

+2

Na pewno tak mi się wydaje. 'putback()' daje możliwość umieszczenia czegoś innego niż ostatnia postać. Jeśli użyjesz tylko 'putback (last_read_character)' efekt jest taki sam, jak wywołanie 'unget()', ale bez wyraźnej gwarancji, że naprawdę "ungetting" ostatni odczytany znak. –

+0

Skończyło się na tym, że użyłem niestandardowego strumienia, który może przywrócić dowolną liczbę znaków. – Puppy

3

To nie jest odpowiedź, której prawdopodobnie oczekujesz, ale chcesz przedstawić moje rozumowanie. Pozostaje dokumentacja, że ​​metody odpowiednio, odpowiednio, są wywoływane. Definicje są następujące:

streambuf :: sungetc

Przesuwa uzyskać wskaźnik o jeden znak do tyłu, przez co ostatni znak zdobyć przez operacji wejścia dostępnego po raz kolejny do następnej operacji wejścia.

Podczas działania funkcja wywoła funkcję zabezpieczonego wirtualnego elementu pbackfail, jeśli wskaźnik get gptr wskaże tę samą pozycję, co początkowy wskaźnik eback.

Drugi:

streambuf :: sputbackc

Wskaźnik dostać się z powrotem do punktu przeniesiony do charakteru tuż przed jego aktualnej pozycji, więc ostatniego znaku zdobyć, c, staje się ponownie dostępny jako znak do odczytania w tej pozycji przez następną operację wprowadzania.

Podczas działania funkcja wywołuje funkcję chronionego wirtualnego członka pbackfail, jeśli znak c nie pasuje gptr() [- 1] lub jeśli wskaźnik get gptr wskazuje na tę samą pozycję, co początkowy wskaźnik eback.

Gdy c nie pasuje do znaku na tej pozycji, domyślna definicja pbackfail w streambuf spowoduje, że c będzie znakiem wyodrębnionym na tej pozycji, o ile jest to możliwe, ale klasy pochodne mogą nadpisać to zachowanie.

Człon funkcja sungetc zachowuje się w podobny sposób, ale bez podejmowania jakiegokolwiek parametru

Jak sputbackc rozmowy pbackfail jeśli postać nie pasuje, to znaczy, że metoda ma sprawdzić, czy wartości są równe. Wygląda na to, że dodatkowy czek jest jedynym obciążeniem, ale nie ma pojęcia, jak jest on rozwiązany w praktyce. Mogę sobie wyobrazić, że jeśli ostatni znak nie jest przechowywany w obiekcie, musi zostać ponownie przeczytany, więc możesz się tego spodziewać nawet wtedy, gdy gwarantuje się, że postacie będą takie same.

Byłem trochę zaniepokojony sytuacją, gdy dzwonimy pod numer unget, ale ostatnia postać nie jest dostępna. Czy wartość parametru putback jest poprawna? Wątpię, ale nie powinno tak być w przypadku plików.

+0

Wygląda na to, że istnieje więcej niż jedna różnica. Wygląda na to, że powrót wygląda tak? Jesteś pewien, że to nie zastępuje. Rozważ wejście "ABC", jeśli czytasz A, następnie B, następnie powrót B, wstawiałby i wstawiał strumień wejściowy "ABBC". Czy to prawda? –

+1

@Xaade, to zależy od implementacji, 'streambuf' domyślnie nic nie robi. 'stringbuf' zastępuje znak w oryginalnym łańcuchu (jeśli ma uprawnienia do zapisu), ale' filebuf' zastępuje znak tylko w buforze wewnętrznym, więc plik bazowy nie jest zmieniony (ale także dekrementy otrzymują wskaźnik, więc nie ma efektu wstawiania nowego znaku do strumień). Więcej szczegółów w specyfikacji: http://www.cplusplus.com/reference/iostream/streambuf/pbackfail/. – tomasz