Domanda
Sto cercando di scrivere un semplice decodificatore UTF-8 per il mio incarico. Sono abbastanza nuovo con C ++ quindi abbi pazienza qui ...
Devo determinare se la codifica è valida o meno, e in entrambi i casi produrre il valore del carattere UTF-8 in esadecimale. Supponiamo di aver letto il primo byte e di aver usato questo primo byte per determinare il numero di byte in questo carattere UTF8. Il problema è che dopo aver letto il primo byte, ho problemi a ripristinare la posizione ifstream di un byte e leggere l'intero carattere UTF-8. Ho provato seekg () e putback (), ma ricevo sempre un errore BUS o un output strano che non sono i miei dati di test. Per favore, grazie.
Anche se posso usare peek () per il primo byte, ma devo ancora leggere i seguenti byte per determinare se la codifica è valida o meno. Il problema di ripristinare la posizione del flusso è ancora presente.
Soluzione
Suggerirei invece di usare peek () per leggere il primo byte. seekg () dovrebbe funzionare per riavvolgere, ma di solito un errore BUS è causato dal codice che interrompe i problemi di allineamento, il che indica che stai facendo qualcos'altro di male nel tuo codice.
Altri suggerimenti
Perché devi cercare indietro? Non puoi semplicemente leggere il resto della sequenza UTF-8, dopo aver saputo quanti altri ottetti ti aspetti?
Vorrei leggere direttamente il byte successivo e aggiungerlo a quello che ho ricevuto. Come ha detto Ates Goral. È un IMHO più pulito.
Ad ogni modo, puoi spostare il puntatore del flusso usando seekg ()
:
char byte = 0;
unsigned int character = 0; // on every usage
ifstream file("test.txt", ios::binary);
file.get(byte);
......
file.seekg(-1, ios::cur); // cur == current position
file.get(
reinterpret_cast<char*>(&character),
numberOfBytesAndNullTerminator);
cout << hex << character;
Attenzione che get ()
nel secondo caso scrive '\ 0'
alla fine del carattere
. Quindi devi dargli il numero richiesto di byte incluso il terminatore null. Quindi, se vuoi leggere due byte == > numberOfBytesAndNullTerminator = 3
.
Non so perché sia ??necessario ricollocare il personaggio, ma istream :: unget () o istream :: putback () dovrebbero fare quello che vuoi. Cercali nella documentazione del tuo compilatore.
cerca:
ifstream::seekg()
ifstream::teellg()