2010-11-11 20 views
10

Jeśli robię coś jak następuje:Dlaczego nie mogę odczytać danych binarnych fstream za pomocą operatora >>?

ifstream file; 
file.open("somefile", ios::binary); 

unsigned int data; 

file >> data; 

Mój strumień zawsze ustawić failbit i data pozostanie niezainicjowany. Jeśli jednak zamiast tego przeczytam char lub unsigned char, strumień jest w porządku. perror() mówi mi "wynik zbyt duży".

Jedyną rzeczą, jaką zobaczyłem w Google była sugestia, mówiąc, że operator>> nie powinny być wykorzystywane do danych binarnych (wolą read()), ale uważam, że operator może być czystsze i łatwiejsze w obsłudze - i nie wymaga rzucając wszystko.

Czy ktoś może wyjaśnić ten problem?

Odpowiedz

10

The iostream extraction operator (>>) próbuje interpretować łańcuchy numeryczne oddzielone białymi znakami, a nie dane binarne. Istnieje wiele różnych sposobów kodowania liczby całkowitej bez znaku w postaci binarnej (na przykład 32-bitowej 2's complement representation w little-endian byte order). Dlatego musisz używać funkcji read/write, aby działać na takich buforach binarnych.

Jednak nic nie stoi na przeszkodzie, aby zaimplementować własną klasę do serializowania danych binarnych w dowolnej formie za pomocą operatorów wstawiania i ekstrakcji. Taka klasa prawdopodobnie używa wewnętrznie funkcji odczytu obiektu ifstream. Alternatywnie, boost serialization library może już zawierać dokładnie to, co chcesz.

0

Powinno to zostać wykonane zgodnie z opisem użytkownika. Jednak projektanci standardu C++ nie są zbyt eleganccy. W rzeczywistości istnieje wiele wad w projektowaniu C++, nawet C++ 11 i C++ 14 ma wiele wad.

Idealny C++ konstrukcja powinna być taka:

1.W pliku tekstowego:

ifstream fin_txt("input.txt"); 
int i; 
float j; 
double k; 
fin_txt >> i >> j >> k; 

To będzie czytać w 3 strun i analizować do liczby całkowitej, float i double, i zapisać je w i, j, i k odpowiednio.

2.W plik binarny:

ifstream fin_txt("input.bin", ios::binary); 
int i; 
float j; 
double k; 
fin_txt >> i >> j >> k; 

To będzie czytać w 4/8 bajtów (w zależności od tego, czy int jest 32-bitowe lub 64-bitowe), 4 bajty i 8 bajtów danych binarnych i przechowywać je do, odpowiednio, i, j, i k.

Niestety, obecny projekt jest zgłoszenie błędu dla przypadku 2. Może to osiągnąć w C++ 22.

+0

Masz powód, dlaczego tak jest w Twojej odpowiedzi: "w zależności od tego, czy int jest 32-bitowe czy 64-bitowe". Obecnie kod używający "" jest przenośny, twoja propozycja nie jest. – Caleth