std::string replace_all()?
-
Hallo,
ich empfange in meinem Programm HTML-Quelltext und möchte diesen dann in einer Textbox darstellen. Wie ihr wisst, muss man dabei unter Windows einen Zeilenumbruch durch CRLF (\r\n) darstellen, die Server senden hingegen meist nur LF (\n).Hat jemand zufällig eine möglichst kompakte Funktion, um alle LF eines std::string durch CRLF zu ersetzen? Ich möchte ungern auf zusätzliche Bibliotheken zurückgreifen und es stattdessen mit Bordmitteln lösen. Oder ist das umständlich und man kann irgendwie einfach dem Server sagen, das er gleich die (für Windows) korrekte Version sendet?
Das Problem ist ja auch, dass ein Suchen nach LF und einfaches Ersetzen nicht ausreicht, da man dann auch Ergebnisse im Falle eines bereits vorhandenen CRLF bekommt und man dann beim Ersetzen schließlich CRCRLF erhalten würde. Und reguläre Ausdrücke gehören ja leider auch nicht zum "Lieferumfang" von C++.
Gruß
ph4nt0m
-
Bist du dir sicher, dass die Textbox entsprechend reagiert? Früher war es mal so, aber ich dachte bei den neuere Windowsversionen sei dies nicht mehr der Fall.
Ansonsten kannst du einfach über
std::string::findnach'\r'suchen, prüfst ob es ein nächstes Zeichen hat, wenn dem der Fall ist schaust du ob es ein'\n'ist, wenn nicht dann fügst du überstd::string::inserteines ein. Danach geht es weiter mit std::string::find, allerdings gibst du nun an, ab wo gesucht werden soll.Grüssli
-
ph4nt0m schrieb:
Hat jemand zufällig eine möglichst kompakte Funktion, um alle LF eines std::string durch CRLF zu ersetzen?
Der C++ Standard hat nichts zu bieten, man muss sich immer alles zusammenfrickeln.
-
Dravere schrieb:
Bist du dir sicher, dass die Textbox entsprechend reagiert? Früher war es mal so, aber ich dachte bei den neuere Windowsversionen sei dies nicht mehr der Fall.
Ja, zumindest die normalen Steuerelemente der Win32-API können mit einem einfachen \n nichts anfangen und drucken dann einen "Kasten".
Dravere schrieb:
Ansonsten kannst du einfach über
std::string::findnach'\r'suchen, prüfst ob es ein nächstes Zeichen hat, wenn dem der Fall ist schaust du ob es ein'\n'ist, wenn nicht dann fügst du überstd::string::inserteines ein.Naja, ein einzelnes \r wird wohl niemals vorkommen, sondern entweder nur ein \n oder eben \r\n. Das Problem ist, dass, wenn ich nach \n suche, ich nicht dieses einfach durch \r\n ersetzen kann, da in Wirklichkeit vor dem gefundenen \n bereits ein \r vorhanden sein könnte. Es scheint nämlich Server zu geben, die bereits "Windows-konform" senden.
Wie auch immer, mit so einigen gesonderten Abfragen habe ich jetzt meiner Meinung nach beide Fälle abgedeckt:
size_t pos = 0; while((pos = str.find(TEXT('\n'), pos)) != std::string::npos) { if(pos == 0 || str.at(pos-1) != TEXT('\r')) str.replace(pos, 1, TEXT("\r\n")); pos += 2; }Wenn ihr spontan irgendwelche Fehler entdeckt, wäre es sehr nett, mir dies mitzuteilen

-
ph4nt0m schrieb:
Naja, ein einzelnes \r wird wohl niemals vorkommen, ...
Gibt es alte Mac Server? *hatte da aus irgendeinem Grund den alten Mac im Hinterkopf*
ph4nt0m schrieb:
Das Problem ist, dass, wenn ich nach \n suche, ich nicht dieses einfach durch \r\n ersetzen kann, da in Wirklichkeit vor dem gefundenen \n bereits ein \r vorhanden sein könnte.
Gleiches Vorgehen wie mit meinem Algo, einfach einen Schritt rückwärts gehen

size_t pos = 0; while((pos = str.find(TEXT('\n'), pos)) != std::string::npos) { if(pos == 0 || str.at(pos-1) != TEXT('\r')) str.replace(pos, 1, TEXT("\r\n")); pos += 2; }ph4nt0m schrieb:
Wenn ihr spontan irgendwelche Fehler entdeckt, wäre es sehr nett, mir dies mitzuteilen

Ja, da gibt es ein paar Fehler.
1. Ich nehme mal an, dassstrein Objekt des Typsstd::stringist, dann ist das MakroTEXThier ganz sicher ein Fehler.std::stringist immer einstd::basic_string<char>. Mit dem MakroTEXTmachst du aber aus den Literalen womöglich einL''oderL""also einwchar_tLiteral.
2. Wieso dieatFunktion? Du kannst hier durch Logik garantieren, dass der Index immer im Bereich der Zeichenkette sein wird, da ist der zusätzliche Aufwand für die Prüfung unnötig. Nimmer lieber denoperator[].
3. Wieso diereplaceFunktion? Du überschreibst ein Zeichen, welches bereits vorhanden ist. Nimm dochstd::string::insert(pos, 1, '\r').Grüssli
-
Danke für deine Antwort.
Zu Punkt 1: Nein, es handelt sich um ein std::basic_string<TCHAR> Objekt und damit sollte das TEXT-Makro doch völlig korrekt sein. Oder gibt es einen anderen/besseren Weg, sein Programm nur durch Änderung einer einzelnen Anweisung/Option wahlweise mit oder ohne Unicode kompilieren zu können?
Die anderen Punkte nehme ich aber dankend an

-
ph4nt0m schrieb:
Zu Punkt 1: Nein, es handelt sich um ein std::basic_string<TCHAR> Objekt und damit sollte das TEXT-Makro doch völlig korrekt sein.
Oh! Ja.
ph4nt0m schrieb:
Oder gibt es einen anderen/besseren Weg, sein Programm nur durch Änderung einer einzelnen Anweisung/Option wahlweise mit oder ohne Unicode kompilieren zu können?
Wie wäre es, wenn du ausschliesslich in Unicode kompilieren würdest? Das wäre zumindest einfacher

Grüssli