Jeśli dobrze zrozumiałem, to masz po prostu odkodować wszystkie liczby (znaki?) zakodowane w utf-8 i sprawdzić czy są zakodowane na odpowiedniej ilości bajtów - tzn. czy przypadkiem nie wykorzystano większej ilości bajtów niż jest to konieczne.
Jeśli macie z tego projekt, to pewnie już to wiesz, ale napisze:
utf-8
dolna wartość (hex) |
górna wartość (hex) |
ilość bitów na kodowaną liczbę |
utf-8 |
0 |
0x7f |
7 |
0xxxxxxx |
0x80 |
0x7ff |
11 |
110xxxxx 10xxxxxx |
0x800 |
0xffff |
16 |
1110xxxx 10xxxxxx 10xxxxxx |
0x10000 |
ox1fffff |
21 |
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx |
Zauważ, że jeśli liczba zakodowana jest na jednym bajcie, to pierwszy (i tutaj ostatni :D) bajt zaczyna się od zera. Jeśli na dwóch bajtach, to od dwóch jedynek i zera, jeśli na trzech to od trzech jedynek i zera, a jeśli na czterech to od czterech jedynek i zera. Wszystkie kolejne bajty zawsze zaczynają się od jedynki i zera, co w żadnym wypadku nie jest 'prefixem' pierwszego bajtu. (przez "zaczyna się" mam na myśli normalny odczyt po ludzku od lewej do prawej, od najstarszych do najmłodszych bitów)
Wiedząc powyższe łatwo* możesz sprawdzić ile bajtów musisz odczytać, żeby odkodować aktualny znak. Najwięcej czasu pewnie zejdzie już na samo odczytywanie zakodowanej wartości, ale też nie powinien to być duży problem.
* - załóżmy, że mam unsigned char (jeden z bajtów pliku), wiem już, że jest pierwszym bajtem jakiejś zakodowanej wartości i chce sprawdzić czy być może rozpoczyna on 4-bajtową reprezentacje - tzn. czy zaczyna się od 11110:
// unsigned char c;
if ((c & 0b11111000) == 0b11110000) {
/* tutaj już wiemy, że `c` zaczyna 4-bajtową sekwencje */
}
// dla czytelności użyłem tutaj notacji binarnej z c++14
// jeśli nie jest dla ciebie dostępna, to możemy to zapisać szesnastkowo
// 0b11111000 == 0xf8, 0b11110000 == 0xf0
Czyli po prostu zostawiam 5 najstarszych bitów (reszte ustawiam na 0) i sprawdzam czy jedynki są tam gdzie być powinny.