Zeichenkette vergleichen



  • @hustbaer Danke für die Info. Bisher bin ich hiermit immer ganz gut gefahren, aber ich probiere eben auch gern andere Dinge aus.

    int __fastcall AnsiCompareText(const System::UnicodeString S1, const System::UnicodeString S2)
    


  • @Gestalt
    Ist das Delphi?
    Soweit ich weiß ist ein UnicodeString UTF-16 kodiert und du kannst ihn ohne Probleme einem std::wstring zuweisen:

    UnicodeString u = L"Wer weiß denn sowas?";
    std::wstring const w = u.c_str();
    

    Vielleicht kommste damit weiter.

    Hab bisher nur wenig mit UTF zu tun gehabt, meiner Meinung nach kann man mit UTF8 nicht arbeiten, das ist eher ein Transportprotokoll, um Textdaten auszutauschen. Wir machen das so, dass wir intern mit std::wstring arbeiten, damit wir solche Probleme wie von @Finnegan beschrieben nicht haben.



  • @wob also das Encoding ist UTF-8 und in den Optionen unter Codepage ist kein Eintrag



  • Dieser Beitrag wurde gelöscht!


  • @DocShoe sagte in Zeichenkette vergleichen:

    Hab bisher nur wenig mit UTF zu tun gehabt, meiner Meinung nach kann man mit UTF8 nicht arbeiten, das ist eher ein Transportprotokoll, um Textdaten auszutauschen. Wir machen das so, dass wir intern mit std::wstring arbeiten, damit wir solche Probleme wie von @Finnegan beschrieben nicht haben.

    Und wo soll das irgendwas davon beheben? Wie hilft wstring dabei?
    Ich finde https://utf8everywhere.org/ sehr hilfreich, es fasst die Argumente gut zusammen.



  • @DocShoe Es gibt auch Fälle wo ich das so mache um einfach mit der STL zu arbeiten. Nur Im Grunde reduziere ich es auf WideString, wchar_t*, da viele Funktionen genau diesen Datentyp erwarten.



  • @wob sagte in Zeichenkette vergleichen:

    @DocShoe sagte in Zeichenkette vergleichen:

    Hab bisher nur wenig mit UTF zu tun gehabt, meiner Meinung nach kann man mit UTF8 nicht arbeiten, das ist eher ein Transportprotokoll, um Textdaten auszutauschen. Wir machen das so, dass wir intern mit std::wstring arbeiten, damit wir solche Probleme wie von @Finnegan beschrieben nicht haben.

    Und wo soll das irgendwas davon beheben? Wie hilft wstring dabei?

    Hab den Eindruck, dass @Gestalt das mit C++ lösen möchte. Ansonsten verstehe ich den ganzen Thread hier nicht, weil AnsiCompareText ja angeblich funktioniert.



  • @DocShoe sagte in Zeichenkette vergleichen:

    Hab den Eindruck, dass @Gestalt das mit C++ lösen möchte.

    Mir ging es um deine Aussage, dass ihr intern einfach wstring nehmt und dann keine Probleme hat. Und das verstehe ich nicht, weil die Probleme doch genauso auftreten. Auch wstring kennt nicht unicode, sondern ist einfach nur eine Aneinanderreihung von mindestens 16 Bit breiten chars. Wie löst das Finnegans Problem, dass ein Zeichen mehrere Darstellungen haben kann? Nicht alle Zeichen passen in ein 16-Bit-wchar. Und so weiter. Deine Aussage war, dass man utf8 nur als Transport gebrauchen kann. Aber ich sehe das nicht.

    Edit: das CompareStringW wurde ja schon genannt, sofern man auf Windows ist.



  • @DocShoe Es funktioniert sehr gut über diese Funktionen auch gibt es Gebietschemaunabhängigen Funktionen IC ich glaube so rum war es , die funktionieren auch sehr gut und auch _TCHAR geht auch alles gut, Beispiel wäre hier _tcsicmp , geht alles , nur wollte ich es über die STL oder BOOST Funktionen bewältigen und zwar auf einfache Art und Weise, aber leider geht es nicht - ja und ich bin auch zu blöd dafür. Was macht jemand der die STL oder Boost benutzt in dem Fall? siehe Ausgangspost. Muss ja ne Lösung geben. Ohne ständig die Bibliotheken zu wechseln.



  • @wob

    Unsere Software ist nicht 100% kompatibel mit allen möglichen UTF-16 Codepoints, wir gehen davon aus, dass sich alle Zeichen als 16bit-Zeichen in der aktuell verwendeten locale darstellen lassen, bzw. wir unterstützen nur solche Sprachen, die diese Bedingung erfüllen.
    UTF8 wird an der Stelle sperrig, wo man auf einzelne Codepoints zugreifen möchte. So Sachen wie

    utf8string utf8 = "Last äkschn Hero";
    utf8[4] = 'Ä' 
    
    oder
    std::reverse( utf8.begin(), utf8.end() );
    

    werden plötzlich kompliziert. Mit std::wstring gibt's diese Probleme nicht mehr, zumindest nicht in unserer Software.
    Vielleicht haben wir die Probleme auch nur, weil wir gewachsene Software mit "konventioneller" String-Behandlung haben, wenn man das modern machen wollte müssten wir vermutlich alles, was irgendwie mit Strings zu tun hat, anfassen.

    Edit:
    Damit unterstützt unsere Software natürlich keine alt-chinesische Kalligraphien. Aber das ist für uns auch nicht wichtig und nicht gefordert.



  • @DocShoe sagte in Zeichenkette vergleichen:

    Wir machen das so, dass wir intern mit std::wstring arbeiten, damit wir solche Probleme wie von @Finnegan beschrieben nicht haben.

    Auch mit std::wstring und sogar mit 32-Bit Code Units wird man immer noch das Problem mit der Normalisierung haben. Es kann natürlich sein, dass die verarbeiteten Strings alle aus einer Datenquelle stammen, wo diese bereits normalisiert sind (das ist vermutlich der Fall, wenn man nur Strings verarbeitet, die z.B. alle aus einem RDBMS kommen). Oder die Daten wurden alle auf die selbe Art eingegeben (ich tippe, dass z.B. ein Windows-Eingabefeld ein ä immer direkt als diese Zeichen und nicht als a mit Verbindungszeichen erzeugt). Gut möglich, dass das Problem einfach noch nicht aufgetreten ist. oder Zumindest nicht so, dass es aufgefallen wäre. Man braucht halt auch erstmal zwei Strings mit unterschiedlichen Codierungen des selben Zeichens.

    Was das "ein Zeichen, ein String-Index" angeht, so funktioniert das mit wstring wahrscheinlich auch häufig. Zumindest für Zeichen aus der Basic Multilingual Plane, die schon eine ganze Menge abdeckt. Aber streng genommen ist das ja auch eine UTF-Format, bei dem ein Zeichen aus mehreren Codepoints bestehen kann. Genau wie bei UTF-8 auch. Wenn man also Unicode vollständig unterstützen will, muss man das sowieso auch mit UTF-16 genau so wie bei UTF-8 berücksichtigen. Das ist auch eines der Argumente von utf8everywhere.org, dass man da auch gleich UTF-8 nehmen kann.

    Von dem, was ein "Zeichen" ist, und dass die auch mit 32-Bit-Codierung mehr als ein Codepoint und damit mehr als einen String-Index haben können fange ich besser nicht an.
    Aber man kommt durchaus auch mit wstring durch, solange man auf keine Sonderfälle stößt. Es ist halt nur leider nicht vollständig korrekt.



  • @DocShoe sagte in Zeichenkette vergleichen:

    Vielleicht haben wir die Probleme auch nur, weil wir gewachsene Software mit "konventioneller" String-Behandlung haben, wenn man das modern machen wollte müssten wir vermutlich alles, was irgendwie mit Strings zu tun hat, anfassen.

    Ja, das wird denke ich ziemlich kompliziert. Ich sehe auch noch viel "gewachsene" Software, die z.B. noch Probleme mit Umlauten hat. Gerade kürzlich wieder in einer Autodesk-Software gesehen bei der Benennung von Objektgruppen.

    Eigentlich müsste man auch einzelne "Zeichen" immer als Substring handhaben. Direkter Index-Zugriff ist da nicht möglich, außer mit einer speziellen String-Datenstruktur die Zeichen-Positionen auf String-Indizes mappt. Das ist immer Suchen+Substring-Operation. Selbst den Index eines "Zeichens"¹ (bzw. "Graphem-Cluster" oder wie auch immer man Zeichen definiert muss man erst "suchen").

    ¹ Ich hatte ja vor einiger Zeit mal ein Beispiel gebracht wie übel das mit den "Zeichen" in Unicode theoretisch werden kann: https://www.c-plusplus.net/forum/topic/353091/sollte-man-heute-mehr-wstring-anstellen-von-string-einsetzen/17. Dass der Browser das überhaupt korrekt rendern, man da beim Text-Markieren auch tatsächlich ganze "Zeichen" intuitiv auswählen und mit der Textsuche sogar mit einem Suchstring ohne die ganzen Akzente den Text finden kann, zeigt schon, wie viel zum Handling von Unicode-Text dazu gehört.



  • @Finnegan allerdings

    UTF8String utf8 = U"Last äkschn Hero";
    utf8.Insert(U"Ä", 4);
    //utf8[4] = 'Ä'; ergibt nur Müll
    ShowMessage( utf8);
    


  • @Gestalt
    Das ist das Tolle an UTF8, die ersten 127 Zeichen sind ASCII und damit kompatibel zu allem, was mit ASCII umgehen kann.



  • @omggg Ein Anwendungsbeispiel und zwar eins wo ich sage das wird niemals passieren aber daran erkennst Du das ein Vergleich über die STL nicht perfekt funktioniert.

    Du wolltest es so 😀

    Dein Programm welches in die Windows-Registry folgendes schreibt "C:\Toolß\test.exe" um einen Autostart zu bewältigen wenn Windows gestartet wird.
    Die test.exe wird gestartet und ließt sogleich aus der Registry diesen Pfad aus und vergleicht diesen mit ihren eigenen Pfad, also "C:\Toolß\test.exe".
    Der Vergleich ist TRUE und in den Optionen der test.exe wird eine CheckBox gesetzt die den Anwender zeigt - ich werde automatisch gestartet.

    Nun, weil ich ja nix anderes zu tun habe als zu testen und lange Weile habe ändere ich auf der Festplatte den Ordnernamen von "Toolß" nach "Toolẞ" um.

    Beim nächsten Windows-Neustart startet wie gewohnt die "test.exe", sie ließt aus der Registry den unveränderten Eintrag "C:\Toolß\test.exe" aus.
    Der Vergleich per STL oder Boost schlägt diesmal aber fehl und in den Optionen der test.exe wird die Checkbox nicht gesetzt und dem Anwender gezeigt das dieses Programm nicht automatisch mit Windows startet.



  • @DocShoe sagte in Zeichenkette vergleichen:

    wir gehen davon aus, dass sich alle Zeichen als 16bit-Zeichen in der aktuell verwendeten locale darstellen lassen

    na dann... füg doch mal einen Violinschlüssel ein, weil du was mit Musik machen willst. Ach, geht nicht?

    Das ist ja genau das Argument, warum wstring eben nicht die Lösung sind. Sie laden zu solchen "halbrichtigen" Lösungen ein. Nehmt doch einfach ASCII und chars. Das ist dann "viertelrichtig"? 😉


  • Gesperrt

    Vielleicht wäre Java doch das richtige Werkzeug ... die Jungs können das nämlich. 😉

    Aber, mehr als ein "Ich möchte, dass das funktioniert, habe aber keine konkrete Anwendung dafür", kann ich erst mal nicht erkennen ... Man kann das große Eszett ja noch nicht einmal über die Tastatur eingeben! ... Andererseits bin ich selber oft auch sehr ehrgeizig, wenn es um Herausforderungen geht - das muss nicht per se ein schlechter Charakterzug sein.



  • @omggg sagte in Zeichenkette vergleichen:

    Aber, mehr als ein "Ich möchte, dass das funktioniert, habe aber keine konkrete Anwendung dafür", kann ich erst mal nicht erkennen ... Man kann das große Eszett ja noch nicht einmal über die Tastatur eingeben! ... Andererseits bin ich selber oft auch sehr ehrgeizig, wenn es um Herausforderungen geht - das muss nicht per se ein schlechter Charakterzug sein.

    Also die Anwendungsfälle könnten durchaus Personalausweise und eID Verfahren sein. Dort sind nämlich viele Angaben in Großbuchstaben angegeben. Dann findet man auch das "ẞ" vor.

    Was man übrigens sehr leicht mit der Kombination ALT GR + Shift + ß eingeben kann.

    Ich schlage vor, vor dem Posten einfach mal nachzudenken.


  • Gesperrt

    Glaube, du hast da ein obligatorisches Downvote vergessen...



  • @wob sagte in Zeichenkette vergleichen:

    na dann... füg doch mal einen Violinschlüssel ein, weil du was mit Musik machen willst. Ach, geht nicht?

    Das ist ja genau das Argument, warum wstring eben nicht die Lösung sind. Sie laden zu solchen "halbrichtigen" Lösungen ein. Nehmt doch einfach ASCII und chars. Das ist dann "viertelrichtig"? 😉

    wchar_t ist das, womit wir aktuell klarkommen und keine Probleme haben. Sobald man (wie auch schon oben beschrieben) vollständig UTF kompatibel sein möchte muss man sich von der Vorstellung ein Zeichen = ein char/wchar_t verabschieden und ggf. die komplette Textbehandlung der Software umkrempeln. Und das ist ein Aufwand, den wir nicht mal abschätzen können, also bleiben wir dabei, solange keine Probleme auftreten.


Anmelden zum Antworten