Forum: PC-Programmierung Wort innerhalb eines strings ersetzen - C++


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Ilarius (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hi, ich zerbreche mir gerade den kopf darüber, wie ich in einem string, 
bestimmte Zeichen ersetzen kann:
ifstream ifs{ "input.txt" };
   if (!ifs) {
      cerr << "Datei kann nicht geöffnet werden.\n";
   }

string s;
getline(ifs,s);
s.replace(s.begin(), s.end(), "KILOGRAMM", "TONNEN");
cout << s;

Naja es fujnktioniert irgendwie nicht, wäre über Hilfestellung sehr 
erfreut :-)

von Wilhelm M. (wimalopaan)


Bewertung
1 lesenswert
nicht lesenswert
Liest mal die Doku.

Die Elementfunktion heißt replace und nicht search-and-replace.

Weißt Du was Iteratoren sind?

von Programmierer (Gast)


Bewertung
0 lesenswert
nicht lesenswert

von Ilarius (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Der Link zu stackoverflow hat geholfen, danke. Die Lösung hatte 
mittlerweile ich auch schon selbst, ist halt etwas indirekt die Lösung, 
dachte es gibt was direkteres, aber es ist eigentlich ok so.

von Rolf M. (rmagnus)


Bewertung
0 lesenswert
nicht lesenswert
Deshalb mag ich die Standardbibliothek an einigen Stellen nicht so 
gerne. Die Dinge sind gerne mal umständlicher als man sich wünschen 
würde. Klar kann man sich die wichtigsten Funktionen auch meistens 
relativ einfach selbst definieren, wie man auf der verlinkten Seite 
sieht. Aber ist es nicht gerade die Aufgabe einer Standardbibliothek, 
sowas schon gleich mitzubringen, statt dass sich da jeder selbst was 
basteln muss?

von Ilarius (Gast)


Bewertung
-1 lesenswert
nicht lesenswert
Rolf M. schrieb:
> Aber ist es nicht gerade die Aufgabe einer Standardbibliothek,
> sowas schon gleich mitzubringen, statt dass sich da jeder selbst was
> basteln muss?

Sehe ich auch so. Das suchen und ersetzen eines Substrings innerhalb 
eines Strings ist etwas so gängiges, dass ich mich gewundert habe, dass 
es da nichts fertiges gibt.

von Wilhelm M. (wimalopaan)


Bewertung
1 lesenswert
nicht lesenswert
Rolf M. schrieb:
> Deshalb mag ich die Standardbibliothek an einigen Stellen nicht so
> gerne. Die Dinge sind gerne mal umständlicher als man sich wünschen
> würde. Klar kann man sich die wichtigsten Funktionen auch meistens
> relativ einfach selbst definieren, wie man auf der verlinkten Seite
> sieht. Aber ist es nicht gerade die Aufgabe einer Standardbibliothek,
> sowas schon gleich mitzubringen, statt dass sich da jeder selbst was
> basteln muss?

Einer der Grundsätze der std-lib ist es, eine (möglichst) orthogonale 
Schnittstelle anzubieten. Dieser Fall eines search-and-replace ist 
ähnlich wie remove-and-erase.

von Programmierer (Gast)


Bewertung
-1 lesenswert
nicht lesenswert
Für eine Rundum-Sorglos-Sammlung an Funktionalität ist eher die 
Boost-Bibliothek zuständig. Da gibt es eine replace_all Funktion:

https://www.boost.org/doc/libs/1_72_0/doc/html/boost/algorithm/replace_all.html

Für so eine einfache Funktion gleich Boost einzubinden ist aber ein 
bisschen Overkill.

von Rolf M. (rmagnus)


Bewertung
-1 lesenswert
nicht lesenswert
Das macht aber die Benutzung unnötig umständlich, weil man eben viele 
Funktionen, die häufig benötigt werden, nicht in der Form findet und 
erst noch selber nachbilden muss. Deshalb arbeite ich letztendlich z.B. 
lieber mit Qt als mit der Standardlib, weil ich da in der Regel eine 
Funktion finde, die das tut, was ich will und ich diese nicht erst aus 
mehreren Bestandteilen, die einzeln eigentlich so gut wie nie nützlich 
sind, zusammenbasteln muss.

Wilhelm M. schrieb:
> ähnlich wie remove-and-erase.

Das fand ich immer etwas daneben. remove ist einfach ein falscher Name, 
da es nichts aus dem Container entfernt, sondern nur verschiebt. Es 
verstößt damit gegen einen der wichtigsten Grundsätze des API-Designs: 
Überraschungen vermeiden.

von Wilhelm M. (wimalopaan)


Bewertung
1 lesenswert
nicht lesenswert
Rolf M. schrieb:
> Das fand ich immer etwas daneben. remove ist einfach ein falscher Name,
> da es nichts aus dem Container entfernt, sondern nur verschiebt. Es
> verstößt damit gegen einen der wichtigsten Grundsätze des API-Designs:
> Überraschungen vermeiden.

Würde ich so nicht sagen: ein remove bedeutet nicht, dass die Elemente 
zerstört werden, sondern nur, dass sie aus dem betrachteten halboffenen 
Intervall entfernt werden. Dies wird deswegen gemacht, um keinen 
Laufzeitnachteil zu haben. Insofern sehr konsequent zu den Designzielen 
der std-lib.

von Rolf M. (rmagnus)


Bewertung
-4 lesenswert
nicht lesenswert
Das ist in der Theorie ja nett, aber wann braucht man das in der Praxis 
mal, ohne dass man die Daten nachher auch wirklich entfernt?

von Wilhelm M. (wimalopaan)


Bewertung
1 lesenswert
nicht lesenswert
Rolf M. schrieb:
> Das ist in der Theorie ja nett, aber wann braucht man das in der Praxis
> mal, ohne dass man die Daten nachher auch wirklich entfernt?

Recht häufig.

Wie gesagt, die C++-stdlib versucht, eine orthogonale Schnittstelle zur 
Verfügung zu stellen. Und da nun mal das Entfernen aus einem Container 
und das Zerstören der Objekte wie auch im echten Leben zwei 
unterschiedliche Operationen sind, wird das auch dort gemacht. Einfach, 
um dem Anwender möglichst große Flexibilität zu gewähren bzw. 
irgendwelche Laufzeitkosten genau dann zu bezahlen, wann er will. Hier 
also bspw. erst, wenn der gesamte Container zerstört wird oder explizit 
eine erase aufgerufen wird. Man kennt das ja aus vielen Bereichen, z.B. 
von IEEE-1003.1 fork()/exec() oder von den IEEE-1003.2 tools nach dem 
Motto: do one thing right.

von Rolf M. (rmagnus)


Bewertung
-1 lesenswert
nicht lesenswert
Wilhelm M. schrieb:
> Wie gesagt, die C++-stdlib versucht, eine orthogonale Schnittstelle zur
> Verfügung zu stellen. Und da nun mal das Entfernen aus einem Container
> und das Zerstören der Objekte wie auch im echten Leben zwei
> unterschiedliche Operationen sind, wird das auch dort gemacht.

Naja, aber im echten Leben heißt "entfernen von Gegenständen aus einer 
Kiste" nicht, dass ich die alle in der Kiste lasse und dort nur in eine 
Ecke lege, sondern dass sie danach wirklich nicht mehr in der Kiste 
sind.

> Einfach, um dem Anwender möglichst große Flexibilität zu gewähren bzw.
> irgendwelche Laufzeitkosten genau dann zu bezahlen, wann er will.

Wobei die Laufzeitkosten durchaus höher sein können als beim direkten 
Löschen, denn die Elemente müssen je nach Container ggf. umkopiert 
werden, um ans Ende zu gelangen.

von Wilhelm M. (wimalopaan)


Bewertung
1 lesenswert
nicht lesenswert
Rolf M. schrieb:
> Wilhelm M. schrieb:
>> Wie gesagt, die C++-stdlib versucht, eine orthogonale Schnittstelle zur
>> Verfügung zu stellen. Und da nun mal das Entfernen aus einem Container
>> und das Zerstören der Objekte wie auch im echten Leben zwei
>> unterschiedliche Operationen sind, wird das auch dort gemacht.
>
> Naja, aber im echten Leben heißt "entfernen von Gegenständen aus einer
> Kiste" nicht, dass ich die alle in der Kiste lasse und dort nur in eine
> Ecke lege, sondern dass sie danach wirklich nicht mehr in der Kiste
> sind.

Du vergisst dabei, dass es auch Container gibt, die in ihrer 
Elementanzahl unveränderlich sind, also bspw. std::array oder statische 
C-Arrays. Hier kannst Du nur logisch löschen (std::remove), denn man 
kann nicht allgemein davon ausgehen, dass jeder DT einen ungültigen Wert 
besitzt (int hat ihn nicht, Zeigertypen haben ihn als nullptr, und wie 
ist das mit Datentyp Xyz?).

>
>> Einfach, um dem Anwender möglichst große Flexibilität zu gewähren bzw.
>> irgendwelche Laufzeitkosten genau dann zu bezahlen, wann er will.
>
> Wobei die Laufzeitkosten durchaus höher sein können als beim direkten
> Löschen, denn die Elemente müssen je nach Container ggf. umkopiert
> werden, um ans Ende zu gelangen.

Zudem werden die Elemente nur verschoben (wenn möglich) und nicht 
kopiert (nur als fallback): das Verschieben etwa eines std::string ist 
sehr billig, das Zerstören recht teuer.

von Oliver S. (oliverso)


Bewertung
0 lesenswert
nicht lesenswert
Rolf M. schrieb:
> Deshalb arbeite ich letztendlich z.B.
> lieber mit Qt als mit der Standardlib, weil ich da in der Regel eine
> Funktion finde, die das tut, was ich will und ich diese nicht erst aus
> mehreren Bestandteilen, die einzeln eigentlich so gut wie nie nützlich
> sind, zusammenbasteln muss.

Was aber vor allem für QString gilt. Da macht Qt einem das Leben schon 
sehr angenehm.

Bei allen anderen Qt-Containern, falls man sie überhaupt nutzt, ist der 
Vorteil gegenüber der Standardf-Bibliothek nicht so ausgeprägt. Als die 
ursprünglich ma eingeführt wurden, mag das anders gewesen sein, 
inwzischen könnte man auf die ganz verzichten.

Oliver

von Programmierer (Gast)


Bewertung
-1 lesenswert
nicht lesenswert
Das ist das schöne an der Konkurrenz, GTKmm - das integriert sich 
praktisch nahtlos mit den Standard-Containern, und erfindet nicht alles 
neu.

von Dirk (Gast)


Bewertung
0 lesenswert
nicht lesenswert
>Was aber vor allem für QString gilt. Da macht Qt einem das Leben schon
>sehr angenehm.

Ja, es macht einem das Leben leichter, aber es hat auch einige 
Stolpersteine z.b.

https://www.kdab.com/a-little-hidden-gem-qstringiterator/
https://stackoverflow.com/questions/43021084/performace-slows-down-when-using-qstringsplit-function

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.