2016-04-27 10 views
-1

Der ISO-8859-5-Standard ist eine Teilmenge des Unicode-Zeichensatzes. Ich möchte testen, ob ein Unicode-Zeichen in einer Zeichenteilmenge von ISO-8859-5 in C++ unterstützt wird. Um dies zu tun, möchte ich eine Funktion wie isLegal unten schreiben, so dass der folgende Code nicht ISO-8859-5 Zeichen herausfiltern wird.Testen Sie, ob ein Unicode-Codepunkt in der ISO-8859-5-Gruppe mit C++ enthalten ist

Angenommen, dass wstring aus einer Unicode-codierten Zeichenfolge stammt.

wstring str = L"AåБ0"; 
vector<char32_t> bytes(str.begin(), str.end()); 
for (vector<char32_t>::const_iterator i = bytes.begin(); i != bytes.end(); ++i){ 
if (isLegal(*i, "ISO-8859-5")) 
{ 
    std::cout << (*i) << ' '; 
} 

}

Der Grund dafür ist, dass ich auf eine Teilmenge der Unicode Obermenge die unterstützten Zeichen begrenzen möchte, so dass der Benutzer keine Zeichen wie Emoji der und Zeichen einreichen kann, die nicht in die unterstützten Sprachen. Danke für Ihre Hilfe.

Gibt es eine einfache Möglichkeit, dies zu tun. Zum Beispiel mit Codecs oder ähnlichem. Zum Beispiel weiß ich über eine Funktion von Qt. Gibt es irgendetwas in diesem Sinne, das mir helfen könnte?

QTextCodec *codec = QTextCodec::codecForName("ISO 8859-5"); 

Oder vielleicht eine Bibliothek da draußen, die das für mich tun würde.

Hinweis: Warum verwende ich wstring? Ich verstehe, dass Unicode-Zeichen zwischen 1 und 4 Bytes pro Zeichen verwenden. Dies ist die Binärdarstellung des Zeichens, die sich von der Darstellung des Zeichens unterscheidet. std: string unterstützt eine Multibyte-Zeichenfolge, aber wenn Sie versuchen, einzelne Zeichen zu isolieren, wusste ich nicht, wo ein Zeichen gestartet wurde und wo es endete, weil die Breite der Bytes in jedem Zeichen inkonsistent war.

So habe ich einen Codec den Multibyte-String in die std :: wstring zu entschlüsseln, die auf wchar_t Templat wird. wchar_t unter Linux ist 4 Byte breit, daher hat jedes Zeichen eine konsistente Breite. Wenn Sie also einen Multibyte-Unicode-Satz in einen wstring setzen, können Sie jedes Zeichen leichter identifizieren, da jedes Zeichen eine konsistente Breite von 4 Bytes hat und alle Unicode-Zeichen in eine 4-Bit-Breite passen, so dass der wstring alle möglichen Zeichen verarbeiten kann Unicode.

+2

Ich stimme diese Frage als off-topic zu schließen, weil es nur ein "Gib mir den Code". –

+0

okay. anscheinend verstehe ich die Kultur hier nicht. Ich suchte nach einer Antwort für ein paar Tage auf Stack over Flow. Ich habe hier nach vielen Jahren der Benutzung der Seite und der Beantwortung von Fragen, wo ich kann, nie eine Frage gestellt. Ich bin gerade dabei, eine Antwort zu finden und werde es veröffentlichen, sobald ich fertig bin. Bitte teilen Sie mir mit, wie ich die Frage umschreiben könnte. –

+0

Wenn Sie den Code selbst zur Verfügung stellen würden, hätten Sie wirklich warten müssen, bis Sie bereit waren, sowohl die Frage als auch die Antwort zu posten, und sie gleichzeitig eingereicht haben. Wir dachten alle, du wolltest, dass wir es einfach für dich tun. Ich stimme wieder zu öffnen; Wenn mehrere andere dasselbe getan haben, können Sie Ihre Antwort posten. –

Antwort

0

Es gibt keine Standard-C++ - Bibliothek für Zeichencode-Konvertierungen. Tatsächlich glaube ich nicht, dass eine C++ - Implementierung mehr als eine Kodierung berücksichtigen muss. Jede Lösung erfordert also eine Bibliothek oder handgemachten Code (d. H. Eine große switch ...).

Da Sie Qt erwähnen, dann ja, sollten Sie in der Lage sein QTextCodec::canEncode zu verwenden:

#include <QDebug> 
#include <QTextCodec> 

#include <string> 

int main() { 
    std::wstring const str = L"AåБ0"; 
    auto const *codec = QTextCodec::codecForName("ISO-8859-5"); 
    if (!codec) { 
     qFatal("Codec not found"); 
    } 

    qDebug() << "Using codec" << qPrintable(codec->name()); 

    for (auto c: str) { 
     if (codec->canEncode(c)) 
      qDebug() << c; 
    } 
} 

Aber das gibt mir

Using codec ISO-8859-5 
65 
229 
1041 
128512 
128580 
128545 
48 

Also das ist eine nicht-Lösung.

+1

Obwohl 'canEncode' tatsächlich gebrochen ist, übergibt man große' c's, für die ein Ersatzpaar erforderlich ist. Sie müssen sie als Ersatzpaare übergeben, die stattdessen in einem QString codiert sind. Sie müssen 'QChar'-Ersatzlogik verwenden, um zu überprüfen, ob ein gegebenes UCS-4' c' als ein einzelnes 'QChar' oder als ein Ersatzpaar darstellbar ist, und von dort gehen. –

+0

@Kuba - Ich hatte nicht bemerkt, dass diese außerhalb von BMP waren. Danke für die Klarstellung. –

+0

Eine Sache, die ich unsicher bin, ist, ob L "foo" erwartet, dass "foo" UTF-8 ist oder was :(Es ist die Implementierung definiert, scheint es, per [diese Antwort] (http://stackoverflow.com/a/ 25568251/1329652) –

0

Für den Moment, als ich diese kundenspezifische Lösung bin mit:

#include <vector> 
#include <string> 
#include <boost/assign/std/vector.hpp> 

using namespace std; 
using namespace boost::assign; 

bool isIntInSet(int val, std::vector<int> set){ 
    if (std::find(set.begin(), set.end(), val) != set.end()) 
    { 
    return true; 
    } 
    return false; 
} 

bool isLegal(int val, string isoNum){ 
    const string ISO8859_5 = "ISO8859-5"; 
    if (ISO8859_5 == isoNum){ 
    vector<int> isoSet5; 
    isoSet5 += 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,0x0028,0x0029,0x002A,0x002B,0x002C,0x002D,0x002E,0x002F,0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039,0x003A,0x003B,0x003C,0x003D,0x003E,0x003F,0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,0x0048,0x0049,0x004A,0x004B,0x004C,0x004D,0x004E,0x004F,0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,0x0058,0x0059,0x005A,0x005B,0x005C,0x005D,0x005E,0x005F,0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,0x0068,0x0069,0x006A,0x006B,0x006C,0x006D,0x006E,0x006F,0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,0x0078,0x0079,0x007A,0x007B,0x007C,0x007D,0x007E,0x00A0,0x0401,0x0402,0x0403,0x0404,0x0405,0x0406,0x0407,0x0408,0x0409,0x040A,0x040B,0x040C,0x00AD,0x040E,0x040F,0x0410,0x0411,0x0412,0x0413,0x0414,0x0415,0x0416,0x0417,0x0418,0x0419,0x041A,0x041B,0x041C,0x041D,0x041E,0x041F,0x0420,0x0421,0x0422,0x0423,0x0424,0x0425,0x0426,0x0427,0x0428,0x0429,0x042A,0x042B,0x042C,0x042D,0x042E,0x042F,0x0430,0x0431,0x0432,0x0433,0x0434,0x0435,0x0436,0x0437,0x0438,0x0439,0x043A,0x043B,0x043C,0x043D,0x043E,0x043F,0x0440,0x0441,0x0442,0x0443,0x0444,0x0445,0x0446,0x0447,0x0448,0x0449,0x044A,0x044B,0x044C,0x044D,0x044E,0x044F,0x2116,0x0451,0x0452,0x0453,0x0454,0x0455,0x0456,0x0457,0x0458,0x0459,0x045A,0x045B,0x045C,0x00A7,0x045E,0x045F; 
    if (isIntInSet(val, isoSet5))return true; 
    } 
    return false; 
} 

Durch eine Liste der sichtbaren Zeichensätze auf http://czyborra.com/charsets/iso8859.html jeden Zeichensatz die Steuerzeichen nicht enthalten aufzublicken, so ist dies nicht der komplette ISO8859- 5 Liste von Zeichen, aber es scheint gut genug für alle druckbaren Zeichen.

+2

Da alle ISO-8859-1-Sätze Erweiterungen von ASCII (einschließlich Steuerzeichen) sind, ist dies auch UTF-8 (ebenso wie Unicode selbst, wenn führende Nullen ignoriert werden.) Sie möchten diesen Test also zerteilen in zwei, eine schnelle Überprüfung für '<128' und eine Suche nach dem Rest. – MSalters

+0

Schöne Idee, das würde es effizienter machen. –

Verwandte Themen