Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Kodowanie UTF 8/16/32 w C++ - przechowywanie znaków

Ostatnio zmodyfikowano 2017-08-25 01:38
Autor Wiadomość
michal11
» 2017-08-23 10:12:52
Przecież to od ciebie zależy jak odczytasz dane binarne z pliku, komputer nic tu magicznie nie robi, jeżeli chcesz odczytać 4 bajty i traktować to jako int, proszę bardzo, pytanie tylko czy dostaniesz sensowne dane jeżeli ktoś to zapisał jako np. float. To samo z liczbami, przecież odczytując to "Ala ma 2 koty" 2 nie czytasz jako liczby tylko jako znak, to samo z większymi liczbami, odczytujesz je cyfra po cyfrze, no chyba, że chcesz to jako liczbę, no ale wtedy widomo jaki typ ma jaki rozmiar.
P-164232
pekfos
» 2017-08-23 12:41:24
mianowicie skąd komputer wie, czy 00 00 2A 00 jest liczbą, a nie znakiem o tym kodzie?
A znak to co niby jest? Liczba.

Ale jak w takim razie komputer alokuje na to pamięć (char czy wchar_t) oraz jak poruszać się po takich indeksach w tablicy (bo raz jeden znak jest zapisany na 4 bitach a raz na jednym)?
Alokacja pamięci w żaden sposób się nie zmienia. Kodowanie to tylko sposób interpretacji wartości. Jak masz znak unicode, który zajmuje 2 wartości wchar_t, to będziesz mieć 2 znaki wchar_t, a nie 1 znak unicode, który pewnie jeszcze jakoś zagnie czasoprzestrzeń żebyś miał go pod jednym indeksem, a nie dwoma.

Dzieje się wtedy magia zwana wyrównaniem.
Wtedy? To znaczy kiedy? I co wyrównanie ma niby wspólnego z tym tematem..?
P-164234
latajacaryba
Temat założony przez niniejszego użytkownika
» 2017-08-23 22:30:35
mianowicie skąd komputer wie, czy 00 00 2A 00 jest liczbą, a nie znakiem o tym kodzie?
A znak to co niby jest? Liczba.
Chodziło mi o to, ze kiedy wczytujemy np. getlinem, to w stringu mamy napis "Ala ma 65 kotów", "a nie Ala ma A kotów" (65 odpowiada A), to znaczy liczba jest traktowana jako liczba, a nie zczytywana jako znak, ale Michal11 to już wyjaśnił.

Tylko jak mam więc odczytać z pliku tekst "Ala ma 2 koty", skoro odczytując to, zamiast znaku '2' otrzymam reprezentację tego znaku w systemie kodowania?

C/C++
int x = 0;
plik.read(( char * ) & x, sizeof x );
std::cout << x; // zrodlo: http://cpp0x.pl/artykuly/?id=72
I co to za zapis
( char * ) & x
 w metodzie read? I po co coś takiego jest robione? Zgadywałbym, że to konwersja na wskaźnik do char, ale ten ampersand mnie niepokoi...


I pytanie z czystej ciekawości: skoro UTF - 32 jest z tego co rozumiem najlepszy (w sensie znaki kodowane tym sposobem zajmują zawsze 4 bajty i nie trzeba jak w UTF - 8 sprawdzać pierwszego bajtu) to dlaczego nie jest on najczęściej stosowany? Czy to zbyt dużo dla pamięci?
P-164248
jankowalski25
» 2017-08-23 23:22:24
Tylko jak mam więc odczytać z pliku tekst "Ala ma 2 koty", skoro odczytując to, zamiast znaku '2' otrzymam reprezentację tego znaku w systemie kodowania?
Nie rozumiem pytania. Odczytasz to, co masz zapisane w pliku. Właściwy sposób odczytywania zależy od zapisanych danych. Jeśli zapiszesz ten tekst jako ASCII, to tak go należy odczytać. Jeśli użyjesz UTF-16 lub UTF-32, to trzeba to odpowiednio uwzględnić. Mając czyste dane binarne można je odczytywać dowolnie, w zależności od potrzeb.

I co to za zapis
( char * ) & x
 w metodzie read?
Rzutowanie
int *
 na
char *
 w stylu C. Lepiej użyć
reinterpret_cast
.

I po co coś takiego jest robione?
Żeby łatwo odczytywać i zapisywać proste struktury. Zakładając, że masz do dyspozycji strukturę POD (Plain Old Data), gdzie masz same typy proste, to można taki twór rzutować na
char *
 i traktować go jako ciąg bajtów. Korzystając z
sizeof
 można uzyskać rozmiar całej struktury i potraktować to tak, jak najzwyklejszy napis w stylu C.

Osobiście wolę unikać takich sztuczek i jawnie określać format, niemniej jednak w wielu przypadkach takie coś zadziała bez większych problemów. Jeśli to ma służyć tylko do wewnętrznego użytku, to spokojnie wystarczy. Przy większych projektach radzę używać jakiegoś istniejącego narzędzia do serializacji, ewentualnie jawnie zdefiniować własny format.

znaki kodowane tym sposobem zajmują zawsze 4 bajty
Przez co wszystkie teksty oparte wyłącznie na ASCII zajmują bez żadnego powodu cztery razy więcej miejsca. Jeśli będziesz intensywnie korzystał ze znaków Unicode mieszczących się na czterech bajtach, to nie odczujesz żadnej różnicy, w każdym innym przypadku otrzymasz dodatkowe zera, które są zbędne.

nie trzeba jak w UTF - 8 sprawdzać pierwszego bajtu
Chodzi o BOM (Byte Order Mark)? Jeśli tak, to nie wszędzie taki znacznik występuje, są nawet narzędzia do jego usuwania z plików, w których przeszkadza zamiast pomagać.
P-164249
latajacaryba
Temat założony przez niniejszego użytkownika
» 2017-08-24 00:28:07
Tylko jak mam więc odczytać z pliku tekst "Ala ma 2 koty", skoro odczytując to, zamiast znaku '2' otrzymam reprezentację tego znaku w systemie kodowania?
Nie rozumiem pytania. Odczytasz to, co masz zapisane w pliku. Właściwy sposób odczytywania zależy od zapisanych danych. Jeśli zapiszesz ten tekst jako ASCII, to tak go należy odczytać. Jeśli użyjesz UTF-16 lub UTF-32, to trzeba to odpowiednio uwzględnić. Mając czyste dane binarne można je odczytywać dowolnie, w zależności od potrzeb.

Mam tu na myśli to, że jeśli odczytujemy dane binarne to mamy je zapisane w postaci 16-kowej, tak znaki jak i liczby. Więc teraz jeśli odczytujemy "Ala ma 2 koty" to skąd komputer wie, że ta dwójka, czyli w zapisie szesnastkowym 0x02 jest liczbą a nie znakiem o numerze 0x02?

Ala ma 2 koty: 0x61 0x20 0x02 0x20 0x6B
Teraz, jeśli wszystko odczytujemy tak jak w kodzie, który podałem na pierwszej stronie tematu (ostatni post) to zostanie to przekonwertowane z tego co rozumiem na znak o kodzie 0x02, zamiast na liczbę

To samo z getline(). Jak komputer "oznacza sobie" co jest liczbą, a co znakiem skoro na pewnym poziomie to wszystko to i tak kod szesnastkowy?
P-164250
michal11
» 2017-08-24 01:01:59
Binarnie to nie znaczy szesnastkowo.

I tak jak pisałem, to jak odczytujesz dane zależy od ciebie a nie od tego jak te dane są zapisane (kwestia tego czy dostaniesz poprawne dane).

getline jest tylko pewną warstwą pośrednią, w zależności od tego jakie parametry mu przekażesz tak odczyta ci dane.

Chociaż wydaje mi, że de odczytywania plików binarnych nie używa się getline jakiś read i odpowiednio traktuje się odczytane dane.
P-164251
Kinexity
» 2017-08-24 01:04:38
Zaspałeś na lekcję o ciągach znaków, czy jak? Ta dwójka też jest trzymana w pamięci jako znak, a nie jako liczba i jej reprezentacja na stówę nie jest 0x02.
P-164252
latajacaryba
Temat założony przez niniejszego użytkownika
» 2017-08-24 01:49:58
No to teraz sporo staje się jasne ;) Źle doczytałem.
Tak więc jak zapisywane są dane w pliku tekstowym i binarnym? https://4programmers.net/C​/Artyku%C5%82y​/Odczyt_i_zapis_plik%C3%B3w_binarnych_w_Cpp#jak-sie-je-odczytuje piszą
Na przykład liczba 42 przechowywana w zmiennej typu int zostanie zapisana jako ciąg bajtów 00 00 00 2A, podczas gdy w pliku tekstowym zostałaby przed zapisaniem przetworzona na znaki '4' i '2', co w formacie ASCII odpowiada bitom 34 i 32.
To w końcu za pomocą liczb w ASCII czy jak? A jak w binarnym?


@Michal11 Tak, to getline to było a propos pliku tekstowego.
P-164253
1 « 2 » 3
Poprzednia strona Strona 2 z 3 Następna strona