Witam.
Eksperymentuję z wczytywaniem plików zapisanych w różnych systemach kodowania i nie wiem do końca w jaki sposób można zmienić rozmiar wczytywanej porcji danych, która zostanie następnie zinterpretowana tzn. nie wiem jak coś takiego osiągnąć w przypadku strumieni w c++. Nie wiem czy poprawnie to opisałem dlatego podam przykłady:
np.
testowy napis:
7a 00 61 00 7c 01 f3 00 42 01 07 01 0a 00 67 00
19 01 5b 01 6c 00 05 01 0a 00 6a 00 61 00 7a 01
44 01 0a 00
wczytywanie w C:
FILE *_file_;
_file_ = fopen( "txt_utf16.txt", "r" );
short arr[36];
fread( arr, sizeof (short), 36, _file_ );
fclose( _file_ );
for ( short it = 0; it < 18; ++it )
wcout << static_cast<wchar_t>(arr[it]);
I jest wszystko ok, tzn mogę podać rozmiar "bloku", tutaj 2 bajty czyli taki jaki ma znak w utf16. O ile wiem, dane są czytane tak czy inaczej bajt bo bajcie, jednak funkcja sama je "łączy" i od razu daje mi numer znaku unicode.
W przypadku użycia ifstream:
ifstream ifs( "txt_utf16.txt", ios_base::in | ios_base::binary );
char arr[36];
ifs.read( arr, 36 );
ifs.close();
for ( short it = 0; it < 36; it += 2 )
{
wcout << static_cast<wchar_t>( (static_cast<unsigned char>(arr[it + 1]) << 8) |
static_cast<unsigned char>(arr[it]) );
}
Wynik ok ale ponieważ zmienna maksymalnie może wynosić bajt, muszę dokonać dodatkowych przekształceń a tego właśnie chcę uniknąć.
Próbowałem też użyć wifstream ale to nie chciało działać poprawnie, poza tym wchar_t nie jest wszędzie taki sam.
Próbowałem również użyć basic_filebuf, niestety też to nie działało tak jak chcę. Z parametrem <char> sytuacja podoba jak z ifstream. Kompilator nie protestuje w przypadku podania czegoś innego niż <char> i <wchar_t>, ale podanie np <short> kończy się marnie. Ostatecznie mógłbym pozostać przy pierwszej, najprostszej metodzie, ale w c++ też pewnie jakoś się da ...
Przy okazji ostatnie pytanie: na ile operacje rzutowania są kosztowne, tzn jest to coś czym należałoby by się przejmować w przypadku prostych typów?