std::string encoding
-
Youka schrieb:
std::string hält Charaktere als char Array, womit diesen jeweils 1 Byte zur Verfügung steht. Wie dieser nun verwendet wird ist im Standard nicht definiert, wobei man für Windows ANSI und für Unix UTF-8 annehmen könnte anhand der Ausgabe durch OS API Funktionen.
Und wie kann man dann ein File mit
fstream (const string& filename, ios_base::openmode mode = ios_base::in | ios_base::out);
richtig öffnen?
Muss ich meine strings Betriebsystem spezifisch konvertieren?
-
muh schrieb:
SeppJ schrieb:
Optimierung auf die Zeichenketten "Hello World!", "Foo", "Bar" und 252 weitere.
Wie willst du das machen?
std::string s = "Foo"; char *c = &s[1]; *c = '!';Die Optimierung merkt natürlich, sobald eine non-const Memberfunktion aufgerufen wird und schaltet dann in den normalen Modus.
-
SeppJ schrieb:
Die Optimierung merkt natürlich, sobald eine non-const Memberfunktion aufgerufen wird und schaltet dann in den normalen Modus.
Ohne bad_alloc?
-
kmp schrieb:
die eigentlich besser über reverse_iterator + find_first_not_of implementiert wären.
Weil du dann Sechs Zeilen Code weniger schreiben musst? Weil es flexibler ist? Aber ich sehe da nur den Umstand, das literarische Programmieren aufzugeben. Der Funktionsname sollte doch schon möglichst für sich sprechen.
-
muh schrieb:
SeppJ schrieb:
Die Optimierung merkt natürlich, sobald eine non-const Memberfunktion aufgerufen wird und schaltet dann in den normalen Modus.
Ohne bad_alloc?
Klar doch! Es ist keine Platzoptimierung. Die Zeichenkette wird ganz normal gespeichert. Und noch ein weiteres Byte, das anzeigt, ob es sich um eine bekannte Sequenz handelt. Bloß die ganzen Suchmemberfunktionen sind optimiert und benutzen einen Lookup-Table für die optimierten Fälle.
-
SeppJ schrieb:
muh schrieb:
SeppJ schrieb:
Die Optimierung merkt natürlich, sobald eine non-const Memberfunktion aufgerufen wird und schaltet dann in den normalen Modus.
Ohne bad_alloc?
Klar doch! Es ist keine Platzoptimierung. Die Zeichenkette wird ganz normal gespeichert. Und noch ein weiteres Byte, das anzeigt, ob es sich um eine bekannte Sequenz handelt. Bloß die ganzen Suchmemberfunktionen sind optimiert und benutzen einen Lookup-Table für die optimierten Fälle.
std::string s = "Foo"; std::string t = "Foo"; char *c = &s[1]; // s welchselt in normalen Modus std::cout << (s == t) << '\n'; // s checkt sich selber erneut nach jedem der 255 Magic-Strings!?
-
muh schrieb:
[code="cpp"]
std::cout << (s == t) << '\n'; // s checkt sich selber erneut nach jedem der 255 Magic-Strings!?[/cpp]Nein, s vergleicht sich einfach mit t. Jeder der Strings kennt zu jeder Zeit seinen genauen Wert.
Selbst wenn dies nicht so wäre, so ist die Komplexität von == nicht vorgegeben. Das wäre dann eben ein Kompromiss bei der Optimierung, dass == langsamer wird, anderes dafür schneller.
-
Sone schrieb:
Nexus schrieb:
Sone schrieb:
PI war auch der Meinung,
std::stringhabe zu viele MemberJa, und da ist er nicht ganz alleine. Das Interface von
std::stringist eine Katastrophe.Dem habe ich nicht widersprochen.
find_first_not_ofmuss aber für Strings in irgendeiner Weise spezialisiert werden, weil es möglich sein sollte es mit einem String-Literal o.ä. aufzurufen.Das es an
std::stringgekoppelt ist ist natürlich doof. Eigentlich sollte das für jeden Container gehen, und eine Überladung fürchar/char16_t/... als Wertetyp ist auch nicht schwer. Nur finde ich es wiederum praktisch, eine Variante instd::stringzu haben die auch Bequem für Strings aufzurufen ist.Ein
find_last_not_ofwie dieses hier*template<typename BidirectionalIterator, typename ForwardIterator, typename ValueT> BidirectionalIterator find_last_not_of( BidirectionalIterator first, BidirectionalIterator last, ForwardIterator first2, ForwardIterator last2 ) { auto iter = last; for(;;) { if( iter == first ) break; if( std::find(first2, last2, *--iter) != last2 ) return iter; } return last; }ist mit Strings umständlicher zu bedienen.
std::string str("ABCDEFGHIJ"); char const ptr[] = "AEIOU"; auto iter = find_last_not_of( std::begin(str), std::end(str), std::begin(ptr), std::end(ptr) );(anstatt
std::string str("ABCDEFGHIJ"); auto pos = str.find_last_not_of("AEIOU");)
Es stimmt jedoch, diese Bequemlichkeit kompensiert die Unflexibilität nicht.
~* Ich konnte nicht widerstehen. Ungetestet.~
Man kann natürlich einfach Überladungen anbieten.
-
Das meinte ich ja, Überladen. (Mit in "irgendeiner Weise spezialisiert", wobei der Begriff Spezialisierung in diesem Kontext natürlich völlig falsch gebraucht wurde)
-
supersonic schrieb:
Und wie kann man dann ein File mit
fstream (const string& filename, ios_base::openmode mode = ios_base::in | ios_base::out);
richtig öffnen?
Muss ich meine strings Betriebsystem spezifisch konvertieren?Das musst du doch wissen. Wer soll die geschriebenen Dateien denn später mal lesen? Wenn sie einem bestimmten Format folgen, gibt dieses oft auch die Zeichenkodierung vor. Viele Formate/Protokolle erlauben auch die Festlegung der Zeichenkodierung in einem Header o.ä.
Wenn du das Format selbst bestimmst, kannst du dir natürlich was aussuchen.
Wenn du fremde Dateien liest, musst du grundsätzlich die entsprechende Kodierung wissen. Wenn dies nicht gegeben ist, kannst du noch rumraten, was aber IMHO nicht empfehlenswert ist. Ich würde heute einfach von UTF-8 ausgehen und dies so dokumentieren. Füttert dich jemand mit ungültigem UTF-8 gibt es etablierte Vorgehensweisen damit umzugehen.
Um die 234 Millionen verschiedenen Legacy-Encodings würde ich mir bei einem neuen Programm keinen Kopf mehr machen. Andernfalls ist mit Kopfschmerzen zu rechnen.
Vorteil an UTF-8 ist auch, dass es eine Obermenge von ASCII ist (Codepoints unter 0x80 werden exakt wie in ASCII kodiert) und insbesondere, dass es keine Nullbytes enthalten kann. D.h. du bekommst keine Probleme mit APIs, denen die Bedeutung der ihnen übergebenen Bytes zwar völlig egal ist, aber keine Nullbytes mittendrin akzeptieren.