UCS-2LE file di testo di analisi
Domanda
Ho un file di testo che è stato creato utilizzando alcuni tool di reporting di Microsoft. Il file di testo include il BOM
0xFFFE
in principio e poi l'output di caratteri ASCII
con valori nulli tra i personaggi (cioè "F.i.e.l.d.1.
"). Posso usare iconv
per convertire questo a UTF-8
utilizzando UCS-2LE
come formato di input e UTF-8
come formato di uscita ... funziona benissimo.
Il mio problema è che voglio leggere in righe dal file UCS-2LE
in stringhe e analizzare i valori dei campi e quindi scriverli in un file di testo ASCII
(vale a dire Field1 Field2
). Ho provato le versioni basate su string
-wstring
e di getline
-. Mentre si legge la stringa dal file, funzioni come substr(start, length)
fanno interpretare la stringa come valori 8-bit
, in modo che i valori di inizio e la lunghezza sono off
Come faccio a leggere i dati UCS-2LE
in una stringa C++
ed estrarre i valori dei dati? Ho guardato boost
e icu
così come numerose ricerche di Google, ma non ho trovato nulla che funziona. Che cosa mi manca qui? Si prega di aiutare!
Il mio codice di esempio si presenta così:
wifstream srcFile;
srcFile.open(argv[1], ios_base::in | ios_base::binary);
..
..
wstring srcBuf;
..
..
while( getline(srcFile, srcBuf) )
{
wstring field1;
field1 = srcBuf.substr(12, 12);
...
...
}
Quindi, se, per esempio, contiene srcBuf
"W.e. t.h.i.n.k. i.n. g.e.n.e.r.a.l.i.t.i.e.s.
", quindi la substr()
sopra restituisce ".k. i.n. g.e
" invece di "g.e.n.e.r.a.l.i.t.i.e.s.
".
Quello che voglio è quello di leggere nella stringa ed elaborarlo, senza doversi preoccupare di rappresentazione multi-byte. Qualcuno ha un esempio di utilizzo boost
(o qualcos'altro) per leggere queste stringhe dal file e convertirli in una rappresentazione larghezza fissa per uso interno?
A proposito, io sono su un Mac con Eclipse e gcc .. E 'possibile la mia STL
non capisce stringhe di caratteri larghi?
Grazie!
Soluzione
substr funziona bene per me su Linux con g ++ 4.3.3. Il programma
#include <string>
#include <iostream>
using namespace std;
int main()
{
wstring s1 = L"Hello, world";
wstring s2 = s1.substr(3,5);
wcout << s2 << endl;
}
stampe "lo, w" come dovrebbe.
Tuttavia, la lettura di file probabilmente fa qualcosa di diverso da quello che ci si aspetta. Converte i file dalla codifica locale a wchar_t, che farà sì che ogni byte di diventare la propria wchar_t. Non credo che la libreria standard supporta la lettura UTF-16 in wchar_t.
Altri suggerimenti
Dopo aver trascorso alcune ore buone affrontare questa domanda, ecco le mie conclusioni:
-
Lettura di un
UTF-16
(oUCS2-LE
) il file è apparentemente gestibile in C ++ 11, vedi Come faccio a scrivere una stringa codificata UTF-8 per un file in Windows, in C ++ -
Dal momento che la libreria
boost::locale
è ora parte di C ++ 11, si può semplicemente utilizzarecodecvt_utf16
(vedi proiettile sotto per esempi di codice eventuali) -
Tuttavia, in compilatori più vecchi (ad es MSVC 2008), è possibile utilizzare
locale
ecodecvt
personalizzato sfaccettatura / "ricetta", come molto ben esemplificato in questa risposta UTF16 scrittura di file in modalità binaria -
In alternativa, si può anche provare questo metodo di lettura, anche se non ha funzionato nel mio caso. Il risultato sarebbe linee che sono state sostituite da caratteri spazzatura mancanti.
Non ero in grado di ottenere questo fatto nel mio pre-C ++ 11 compilatore e dovuto ricorrere a script in Ruby e creando un processo (è solo in prova in modo Credo che questo tipo di complicazioni sono ok lì) per eseguire il mio compito.
Spero che questo non risparmia altri po 'di tempo, felice di aiutare.