2012-05-12 16 views

Odpowiedz

35

IOstreams używają streambufs jako źródła/celu wejścia/wyjścia. W efekcie, rodzina streambuf wykonuje całą pracę związaną z IO, a rodzina IOstream jest używana tylko do formatowania i transformacji ciągów/łańcuchów.

Teraz istream_iterator bierze argument szablonu, który mówi co niesformatowany string-sekwencja z streambuf powinien być sformatowany jako, jak istream_iterator<int> zinterpretuje (spacje rozdzielany) cały tekst przychodzącego jak int s.

Z drugiej strony, istreambuf_iterator dba tylko o nieprzetworzone znaki i wykonuje iteracje bezpośrednio nad powiązanym strebusem z istream, że zostanie przekazany.

Ogólnie rzecz biorąc, jeśli interesują Cię wyłącznie surowe znaki, użyj numeru istreambuf_iterator. Jeśli interesuje Cię sformatowane wejście, użyj istream_iterator.

Wszystko, co powiedziałem, dotyczy również ostream_iterator i ostreambuf_iterator.

+0

"Ogólnie rzecz biorąc, jeśli interesują cię jedynie surowe znaki, użyj" istream_iterator "- czy to powinno być" istreambuf_iterator "? – Mankarse

+0

@Mankarse: Erm, oczywiście, dzięki. – Xeo

+0

To sprawiło, że stało się to dla mnie bardziej jasne, dzięki! – dextrey

7

Oto naprawdę źle utrzymany sekret: iostream per se, nie ma prawie nic wspólnego z faktycznym odczytaniem lub zapisaniem z/do pliku na komputerze.

iostream zasadzie działa jako „swata” między streambuf i regionalne:

enter image description here

sklepach IOStream niektóre państwa, jak konwersje powinny być wykonane (np bieżącą szerokość i precyzję dla konwersja). Używa ich do kierowania lokalizacją, jak i gdzie przeprowadzić konwersję (np. Przekształcić tę liczbę w ciąg znaków w tym buforze o szerokości 8 i dokładności 5).

Mimo że nie zapytano bezpośrednio o to, locale z kolei jest w rzeczywistości tylko pojemnikiem - ale (dla raczej dziwactwa) pojemnikiem heterogenicznym typu. Rzeczy, które zawiera, to facet s. Obiekt facet definiuje pojedynczy aspekt ogólnego ustawienia narodowego. Standard definiuje liczbę aspektów dla wszystkiego, od czytania i pisania liczb (num_get, num_put) do klasyfikowania znaków (aspekt aspektu).

Domyślnie strumień używa ustawienia narodowego "C". To dość proste - liczby są konwertowane jako strumień cyfr, jedyne, co rozpoznaje jako litery, to 26 małych liter i 26 wielkich liter angielskich, i tak dalej. Możesz jednak imbue przesłać strumień z różnymi ustawieniami narodowymi do wyboru. Możesz wybrać ustawienia regionalne, których chcesz używać według nazw określonych w łańcuchach. Szczególnie interesujący jest taki, który został wybrany przez pusty ciąg znaków. Użycie pustego ciągu w zasadzie mówi bibliotece środowiska wykonawczego, aby wybrało ustawienia regionalne, które "myśli" są najbardziej odpowiednie, zwykle w oparciu o to, jak użytkownik skonfigurował system operacyjny. Pozwala to kodowi na przetwarzanie danych w zlokalizowanym formacie, bez wyraźnego zapisu dla konkretnych ustawień narodowych.

Tak, podstawowa różnica między istream_iterator i istreambuf_iterator jest to, że dane pochodzące z o istreambuf_iterator nie przeszedł (większość) przekształceń dokonanych przez lokalizacji, ale dane wychodzące o istream_iterator został zwerbowany według ustawień regionalnych.

Na co warto, że „większość” w poprzednim akapicie odnosi się do faktu, że podczas odczytu danych z istreambuf (przez iterator lub w inny sposób) jeden trochę transformacji locale oparte jest done: wraz z różnymi rodzajami "formatowania", ustawienia narodowe zawierają aspekt kodeków, który jest używany do konwersji z niektórych zewnętrznych reprezentacji do niektórych wewnętrznych reprezentacji (np. UTF-8 do UTF-32).

może więcej sensu, aby ignorować faktu, że są one zarówno przechowywane w regionie, a myśleć tylko o poszczególnych aspektach związanych:

enter image description here

Więc to jest prawdziwa różnica między istream_iterator i istreambuf_iterator. Trochę transformacji (co najmniej potencjalnie) wykonuje się dla danych z jednego, ale zasadniczo wykonuje się dane z adresu pochodzącego z .

+0

Dobre wyjaśnienie. A co z tym, że używanie stregarufs bezpośrednio do surowych danych binarnych jest możliwe? – Pavel

+0

@Pavel: To nie działa jak iostream C++, ale przynajmniej teoretycznie, nie ma powodu, dla którego nie mogliby. Wątpię jednak, byś chciał - gdybyś tak zrobił, musiałbyś zastosować konwersję 'codecvt' po jednej nazwie na raz, gdy czytasz dane z surowego bufora, który, jak sądzę, normalnie straciłby ilość prędkości (w porównaniu do konwersji całego bufora na raz). –

+0

To jest powód, dla którego nie chcę używać iostreams, ponieważ nie chcę, aby ten kodek był zaangażowany. – Pavel