Charset Frage
-
@Swordfish sagte in Charset Frage:
Windows: ...
Das mutet schon etwas barock an
Interessant ist aber der der Ansatz, dass man die Umwandlung natürlich (theoretisch) etwas simpler hinbekommt, indem man die aus mehreren Code Units bestehenden UTF-16 Code Points einfach aussen vor lässt. Damit deckt man natürich nicht den gesamten Unicode-Bereich ab, aber je nach Anwendungsgebiet kann das schon ausreichen und den Code etwas vereinfachen. Vielleicht noch den zulässigen Wertebereich einschränken, damit die Funktion kein ungültiges UTF-16 erzeugen kann? Das würde ich jedenfalls nicht in die Hand desjenigen legen wollen, der die JSON-Datei schreibt
Hätte ich das manuell gemacht, anstatt es an
std::wstring_convert
zu delegieren, wäre das Ganze deutlich länger geworden.Auch das mit dem
_setmode(_fileno(stdout), _O_U16TEXT)
kannte ich noch nicht. Könnte das vielleicht eine halbwegs portable Lösung sein, um die Konsole auf UTF-16 umzustellen? Linux kennt diese Funktion meines Wissens ebenfalls (wenn auch glaube ich ohne die Unterstriche).
-
@Skared sagte in Charset Frage:
vielen Dank an alle. Ich habe mein Problem mit eurer Hilfe lösen können
Noch ein wichtiger Hinweis: Die Konvertierung in meinem Code kann einen
std::range_error
werfen (siehe hier). Das kann je nachdem wo die JSON-Daten herkommen, durchaus öfter mal passieren und sollte dein Programm nicht unbedingt "crashen" lassen.Entweder du fängst das entsprechend ab, oder konstruierst das
std::wstring_convert
-Objekt in Zeile 32 so:std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> convert{ "<invalid character>" };
Der im Konstruktor übergebene String wird dann in Fehlerfall in den konvertierten String eingefügt anstatt dass eine Exception geworfen wird.
-
@Finnegan sagte in Charset Frage:
Das mutet schon etwas barock an
Was gefällt Dir daran nicht? Na gut, einen stringstream auf eine immer 4-stellige Zahl zu werfen ist overkill.
-
@Swordfish sagte in Charset Frage:
@Finnegan sagte in Charset Frage:
Das mutet schon etwas barock an
Was gefällt Dir daran nicht? Na gut, einen stringstream auf eine immer 4-stellige Zahl zu werfen ist overkill.
Das, und man hätte vielleicht auch noch irgendwie den restlichen Schleifenkörper in den Kopf bekommen können
Ein
indicator
vom Typstd::string
würde den Code auch etwas übersichtlicher machen, wenn die Variable eh nichtconstexpr
ist (brauchts auch nicht wegen Effizienz, Konstantenfaltung wird das schon regeln).Die String-Kopiererei mit den ganzen
malloc
s unter der Haube hab ich allerdings auch drin. Für den Feinschliff würd ich das wohl mitstring_view
s machen. So ein Algorithmus braucht eigentlich nur auf dem Eingabe- und dem Ausgabestring zu arbeiten.
-
@Finnegan sagte in Charset Frage:
wenn die Variable eh nicht constexpr ist
Ein
constexpr
Stringliteral? Wie geht das?
-
@Swordfish sagte in Charset Frage:
@Finnegan sagte in Charset Frage:
wenn die Variable eh nicht constexpr ist
Ein
constexpr
Stringliteral? Wie geht das?Nicht das Literal selbst, sondern die Variable
indicator
(constexpr const char* indicator = "[u]";
). Gesetzt den Fallstd::strlen
wäre ebenfallsconstexpr
(theoretisch machbar, aber leider nicht der Fall, müsste man selbst implementieren), kannindicator_length
dann ebenfallsconstexpr
sein. So wie ich das sehe, könnte der Compiler am Anfang deiner Funktion ansonsten auch einen eigentlich unnötigenstrlen
-Call generieren, der dann jedes mal aufgerufen wird.Letztendlich dürften moderne Compiler jedoch schlau genug sein um auch ohne
constexpr
zu erkennen, dassindicator_length
zur Compile-Zeit berechnet werden kann und das auch tun. Besonders beistrlen
, wo Compiler meines Wissens schon lange solche Optimierungen machen. Ich hatte ja geschrieben, dass das wegen Konstantenfaltung wohl nicht wirklich nötig ist.Oder habe ich was übersehen/falsch verstanden?
-
@Finnegan sagte in Charset Frage:
Oder habe ich was übersehen/falsch verstanden?
Weiß nicht, für eine constexpr-Funktion müssen doch alle Parameter auch constexpr sein? Aber ein pointer kann nicht constexpr sein soweit ich mich erinnere?
-
@Swordfish sagte in Charset Frage:
Aber ein pointer kann nicht constexpr sein soweit ich mich erinnere?
Aber sicher:
constexpr const void * p = nullptr;
-
@wob Ich steh vielleicht auf einer dicken fetten Leitung, aber da ist doch der pointee constexpr und nicht der pointer.
-
Schau dir mal an:
int i = 42; int main() { constexpr int * p = &i; *p = 0; // geht // p = nullptr; // fails to compile: cannot assign to variable 'p' // with const-qualified type 'int *const' return *p; }
Durch mein zusätzliches
const
im Vorposting war auch der Pointeeconst
.Edit: ich hatte ehrlich gesagt überhaupt nicht über Pointer/Pointee-constness nachgedacht, sollte eigentlich auch mit dem
void * = nullptr
ein unnützer Spaß gewesen sein.
-
@wob ok, danke.