2009-08-08 7 views
2

Ich habe eine Textdatei, die mit einem Microsoft Reporting Tool erstellt wurde. Die Textdatei enthält die BOM0xFFFE am Anfang und dann ASCII Zeichenausgabe mit Nullen zwischen Zeichen (d. H. "F.i.e.l.d.1."). Ich kann verwenden, um dies in UTF-8 mit UCS-2LE als Eingabeformat und UTF-8 als Ausgabeformat zu konvertieren ... es funktioniert gut.UCS-2LE Textdateianalyse

Mein Problem ist, dass ich in den Zeilen aus der UCS-2LE Datei in Strings lesen möge und die Feldwerte analysieren und sie dann zu einer ASCII Textdatei schreiben (das heißt Field1 Field2). Ich habe versucht, die string und -basierte Versionen von getline - während es liest die Zeichenfolge aus der Datei, Funktionen wie substr(start, length) interpretieren die Zeichenfolge als 8-bit Werte, so dass die Start-und Längenwerte aus sind. Wie kann ich die UCS-2LE Daten in eine C++ Zeichenkette einlesen und die Datenwerte extrahieren? Ich habe boost und icu sowie zahlreiche Google-Suchen angeschaut, aber nichts gefunden, was funktioniert. Was fehlt mir hier? Bitte helfen Sie!

Mein Beispiel-Code sieht wie folgt aus:

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); 
    ... 
    ... 
} 

Also, wenn zum Beispiel srcBuf "W.e. t.h.i.n.k. i.n. g.e.n.e.r.a.l.i.t.i.e.s." enthält dann die substr() oben returns ".k. i.n. g.e" statt "g.e.n.e.r.a.l.i.t.i.e.s.".

Was ich will, ist in der Zeichenfolge zu lesen und zu verarbeiten, ohne sich um die Multi-Byte-Darstellung kümmern zu müssen. Hat jemand ein Beispiel dafür, boost (oder etwas anderes) zu verwenden, um diese Zeichenfolgen aus der Datei zu lesen und sie für den internen Gebrauch in eine feste Breite zu konvertieren?

BTW, ich bin auf einem Mac mit Eclipse und gcc .. Ist es möglich, dass meine STL breite Zeichenfolgen nicht versteht?

Dank!

Antwort

0

substr funktioniert gut für mich auf Linux mit g ++ 4.3.3. Das Programm

#include <string> 
#include <iostream> 

using namespace std; 

int main() 
{ 
    wstring s1 = L"Hello, world"; 
    wstring s2 = s1.substr(3,5); 
    wcout << s2 << endl; 
} 

druckt "lo, w", wie es sollte.

Die Datei liest jedoch wahrscheinlich etwas anderes als erwartet. Es konvertiert die Dateien aus der Gebietsschema-Codierung in wchar_t, wodurch jedes Byte ein eigenes wchar_t wird. Ich glaube nicht, dass die Standardbibliothek das Lesen von UTF-16 in wchar_t unterstützt.

+0

Danke für die Antwort. Ich sehe das gleiche Verhalten. Wie du sagst, ich glaube nicht, dass UTF-16 nach wchar_t unterstützt wird. Ich habe iconv verwendet, um die Datei nach UFT-8 zu konvertieren und sie nach Problem zu lösen. – Cryptik

+0

Obwohl ich hier wahrscheinlich Geister anspreche, sollte @Cryptik seine Frage als gelöst markieren :) – Dr1Ku

1

ein paar gute Stunden verbracht haben, diese Frage anzugehen, hier sind meine Schlussfolgerungen:

  • eine UTF-16 (oder UCS2-LE) Datei zu lesen, ist offenbar überschaubar in C++ 11, siehe How do I write a UTF-8 encoded string to a file in Windows, in C++

  • Seit die boost::locale Bibliothek ist jetzt Teil von C++ 11, man kann einfach codecvt_utf16 verwenden (für mögliche Code-Beispiele siehe unten)

  • In älteren Compilern (z.B.MSVC 2008), können Sie locale und eine benutzerdefinierte codecvt Facette/„Rezept“ verwenden, wie sehr schön in this answer-Writing UTF16 to file in binary mode

  • Alternativ Beispiel kann man auch this method des Lesens versuchen, obwohl es nicht in meinem Fall nicht funktioniert. Die Ausgabe würde fehlende Zeilen sein, die durch Müllzeichen ersetzt wurden.

war ich nicht in der Lage diese 11-Compiler zu erhalten getan ++ in meinem Pre-C und hatte es in Ruby greifen, um Skripts und Laichen einen Prozess (es ist nur in Test so denke ich, diese Art von Komplikationen sind ok) um meine Aufgabe auszuführen.

Hoffen, das spart andere einige Zeit, glücklich zu helfen.