Multi-Byte Zeichen vergleichen?
-
inline bool is_ae(const char c) { return c == '\204'; }
-
Thuruk schrieb:
inline bool is_ae(const char c) { return c == '\204'; }Das
constgibt keine Sicherheit,inlineist unnötig.
-
Naja man spart einen unnötigen Funktionsaufruf, und ich denke nicht dass das Programm dadurch länger wird.
-
Thuruk schrieb:
Naja man spart einen unnötigen Funktionsaufruf, und ich denke nicht dass das Programm dadurch länger wird.
Bei halbwegs modernen Compilern werden alle Funktionen automatisch geinlined, wenn das legen der Rücksprungadresse und der Parameter auf den Stack, das Anspringen der Funktion, das freigeben der Parameter (eigener scope) und das Zurückspringen zu lange dauern würde.
-
Das Problem ist: Man bekommt den numerischen Wert von ä nicht ein char. Von daher kann das nicht funktionieren, UTF-8 kodiert ist ein ä 2 char lang.
(Falls ich gerade voll neben der Spur bin und ein ä sehr wohl in 8bit passt, dann merke ich an, dass ich andere Zeichen meine und ä nur ein Beispiel war
)
-
In dem Fall könnte man auch 2 Zeichen vergleichen. Pointer auf das erste übergeben, vergleichen, erhöhen, vergleichen.
-
inline bool twobytescmp(char *ptr) { return *ptr == 'l' && *(ptr+1) == 'o'; }Sry falls ein Bug drinnen ist denke so passt es.
-
Ethon schrieb:
(...)
Und da liegt mein Problem:
bool is_ae(char c) { return c == 'ä'; }Das kann ja nicht funktionieren? Was bleibt mir an Optionen außer einem direkten Stringvergleich? Denn eine solche Funktion muss mit Iteratorenpaaren auskommen ...
Mal angenommen dass du bereits irgendwo sicherstellst dass das was der Lexer verarbeitet gültiges UTF-8 ist, und z.B. nicht mit irgendwas aufhört wo laut Byte N noch ein Byte N+1 folgen müsste, aber Byte N schon das letzte ist... dann ...
bool is_ae(char* p) { return decode_utf8(p) == Unicode_ae; }Tadaaa
Sonst könntest du noch den Text während der Bearbeitung in UCS-4 verwandeln. z.B. über spezielle "Iteratoren", die zwar intern mit (unsigned) char-Zeigern arbeiten, aber beim Dereferenzieren/Inkrementieren/... das UTF-8 Encoding berücksichtigen. Also beim Lesen immer nen UCS-4 Wert zurückgeben und beim Inkrementieren eben um einem kompletten Codepoint weiterrücken.
Obwohl hier etwas "Range-artiges" vermutlich besser wäre, weil leichter zu implementieren und u.U. auch leichter zu handhaben.Oder du bleibst einfach bei UCS-4 und konvertierst vorher alles im RAM.
-
Oder man macht sich eine Klasse Char, die mehrere char enthält, statt überall char* rum zu werfen.
-
Ginge es denn nicht mit Templates?
template<typename ch_t> bool is_ae(ch_t c) { return c == static_cast<ch_t>('\204'); }
-
Hacker schrieb:
Ginge es denn nicht mit Templates?
template<typename ch_t> bool is_ae(ch_t c) { return c == static_cast<ch_t>('\204'); }Schau dir mal an was UTF-8 ist.
http://www.utf8-zeichentabelle.de/ Suche das ä.
-
Hacker schrieb:
Das
constgibt keine Sicherheit,inlineist unnötig.An dieser Stelle nicht. Der Code ist kein template und es gibt keinen Hinweis darauf, dass der Code innerhalb einer Klasse steht. Ohne inline führt das nach ODR zu Linkerfehlern.
The more you know.
-
pschiuuuuuuu schrieb:
Oder man macht sich eine Klasse Char, die mehrere char enthält, statt überall char* rum zu werfen.
Aber das macht ja schon wchar_t.
Okay, ihr habt mich überzeugt, ich versuche einfach nicht mehr normale chars zu supporten, danke (besonders an hustbaer).
-
wchar_t ist auch nur bedingt geeignet, denn GCC/Linux meint dass wchar_t 4 Byte breit ist, MSVC/Windows meint dass wchar_t 2 Byte breit ist.
Nimm (u)int32_t.
-
otze schrieb:
Hacker schrieb:
Das
constgibt keine Sicherheit,inlineist unnötig.[...]
Ohne inline führt das nach ODR zu Linkerfehlern.So pauschal ist das nicht richtig. Ich habe in meinen Codes jede freier Funktionen ohne das Schlüsselwort inline deklariert und definiert ohne Linkerfehler zu bekommen.
-
Belli schrieb:
otze schrieb:
Hacker schrieb:
Das
constgibt keine Sicherheit,inlineist unnötig.[...]
Ohne inline führt das nach ODR zu Linkerfehlern.So pauschal ist das nicht richtig. Ich habe in meinen Codes jede freier Funktionen ohne das Schlüsselwort inline deklariert und definiert ohne Linkerfehler zu bekommen.
Und die waren in Header-Dateien?
-
Nö, wieso sollten sie? Steht hier etwa irgendwo, dass die hier in Rede stehende Funktion in einer Header-Datei ist?
Edit: Die Deklarationen waren in Header-Dateien, die Definitionen nicht ... ist das nicht der übliche Weg?
-
"nach ODR zu Linkerfehlern" ist doch sowieso quatsch.
Der Standard kennt die ODR, aber keine Linker.
Bei ODR violations sind auch "no diagnostics required".
-
hustbaer schrieb:
"nach ODR zu Linkerfehlern" ist doch sowieso quatsch.
Der Standard kennt die ODR, aber keine Linker.
Bei ODR violations sind auch "no diagnostics required".*seufz* *reicht dir eine Korinthe*
-
Naja, es is halt doof wenn man davon ausgeht dass man nen Fehler bekommt wenn man was falsch macht, aber eben keinen bekommt.
Wie es z.B. passiert wenn man ne Inline Funktion in mehreren Übersetzungseinheiten unterschiedlich definiert.Das ist nämlich auch ne ODR Verletzung. Dem Compiler/Linker ist das bloss vollkommen egal, die prüfen das nicht.