Chce odczytać tekst zakodowany w UTF-8 bajt po bajcie z analizą czy dany znak jest jedno czy dwubajtowy.
Nie chcę gotowych wbudowanych metod do tego Chce taką metodę napisać samemu.
W związku są 2 problemy:
1. Rozpoznanie czy odczytany bajt to znak 1 czy 2 bajtowy
2. Konwersja bajtu lub bajtów na typ char
W pierwszym wypadku to rozumiem, że jest jakaś maska aby rozszyfrować czy odczytany bajt odpowiada za znak jedno czy dwubajtowy. Ale tutaj trzeba zrobić porównanie wykorzystując operatory bitowe chyba z iloczynem bitowym. Tak mi się wydaje.
W drugiej sytuacji jak mamy znak 1 bajtowy to nic nie robimy poza konwersja bajta na char, a jeśli znak jest dwubajtowy ?
Tutaj to pewnie trzeba będzie z przesunięć bitowych korzystać. Tylko jak to zrobić jak już odczytam załóżmy znak 2 bajtowy, to pierwszy bajt przypisuje do char z przesunieciem bitowym o 8 w lewo ? No tak ale jak wstawić drugi bajt ? nie kasując pierwszego. To nie powinno być trudne ale ja widocznie już nie myślę przez tą pogodę. Z góry dziękuję za pomoc
Odczyta bajt po bajcie tekstu w kodowaniu UTF-8
Rozpoczęty przez
macsurf
, 23 lip 2014 17:36
4 odpowiedzi w tym temacie
#1
Napisano 23 lipca 2014 - 17:36
#2
Napisano 23 lipca 2014 - 19:02
Nie chcę Cię martwić, ale masz błąd w samych założeniach. W UTF-8 znaki są kodowane w sekwencjach od jednego do czterech bajtów (8-32 bitów). Jak chcesz samemu bawić się w analizę plików to musisz to uwzględnić, albo wyłożysz się na użyciu pierwszego znaku mającego więcej jak dwa bajty.
#3
Napisano 23 lipca 2014 - 19:34
Chyba posta mi zjadło.
W moim przypadku w grę wchodzą znaki, które zajmują 1 lub 2 bajty dlatego nie pisałem o szerszym zakresie
#4
Napisano 23 lipca 2014 - 21:14
To ryzykowne założenie, wiele razy widziałem pliki napisów (subtitles) kodowane w UTF-8, które miały dodatkowe znaczki wykraczające poza dwa bajty (bo autor postanowił sobie udekorować napisy).
Ja używam systemowych metod, więc po prostu miałem jakiś krzaczek, ale plik się wczytał w całości. W Twoim przypadku takie założenie spowoduje błędną interpretację pliku.
BTW jak odczytywać pliki w UTF-8 bajt-po-bajcie masz opisane w RFC dla tego formatu (RFC 3629 dla ISO 10646), zauważ, że tylko część bitów w każdym bajcie znaku wielobajtowego jest kodująca, reszta to znaki sterujące.
Generalnie powinieneś skorzystać z tego RFC: z każdego odczytanego bajtu wybrać tylko bity kodujące umieszczając je w docelowej zmiennej, a następnie korzystając z tej zmiennej odczytać znak z tablicy kodującej
#5
Napisano 23 lipca 2014 - 21:18
Jest coraz bliżej zacząłem od końca rozwiązywania problemu
Tyle, że zamiast chara przekształcałem 1 inta na 2 bajty dla zachowania analogii z charem.
Dobra teraz z powrotem posklejac 2 bajty do 4 bajtowego inta:
Tutaj uwaga, natkąłem się na mały problem, który trochę mi napsuł krwi.
Musiałem zastosować iloczyn bitowy na lb2, gdyż w niektórych liczbach które w reprezentacji bitowej w typie byte miały na początku 1 po konwersji na int`a powstawało na początku 24 jedynki + 8 bitów naszej wlaściwej liczby, więc trzeba było zastosować ową maskę 0xFF aby usunąć niechciane jedynki.
Dobra teraz rozpoznawanie typu znaku pozostało ( 1 czy 2 batjowy ), ale to zostawiam na jutro. :evil:
Tyle, że zamiast chara przekształcałem 1 inta na 2 bajty dla zachowania analogii z charem.
int liczba = 3256; // typ 32-bitowy: liczba zajmuje 2 bajty w 4 bajtowym int`cie - mała analogia do chara ;) byte lb1 = (byte)(liczba>>8); // pierwsza czesc 8 bitów byte lb2 = (byte)liczba; // druga czesc 8 bitow
Dobra teraz z powrotem posklejac 2 bajty do 4 bajtowego inta:
int liczba2 = (int)lb1; // zapisanie pierwszych 8 bitów liczba2 <<= 8; // przesuniecie ich o 8 bitów w lewo, a tym samym wyzerowanie 8 najmniej ważnych bitów dla zapisu drugiego bajta lb2 liczba2 = ( liczba2 | ((int)lb2 & 0xFF));
Tutaj uwaga, natkąłem się na mały problem, który trochę mi napsuł krwi.
Musiałem zastosować iloczyn bitowy na lb2, gdyż w niektórych liczbach które w reprezentacji bitowej w typie byte miały na początku 1 po konwersji na int`a powstawało na początku 24 jedynki + 8 bitów naszej wlaściwej liczby, więc trzeba było zastosować ową maskę 0xFF aby usunąć niechciane jedynki.
Dobra teraz rozpoznawanie typu znaku pozostało ( 1 czy 2 batjowy ), ale to zostawiam na jutro. :evil:
Użytkownicy przeglądający ten temat: 0
0 użytkowników, 0 gości, 0 anonimowych