C-Strings vergleichen
-
Ja, ich weiß dass ihr wisst, wovon Ihr sprecht.
Aber ich denke es ist doch mal Geschmackssache, ob man std::string oder char array[50] verwendet.
Außerdem übersiehst du eine Sache für die es gut sein könnte, es zu wissen :
Deine C-Strings liegen immernoch im speicher und werden sogar verdopelt wenn du nen std::string damit initialiesiert. Das sollte man zumindest wissen um Schpeicherlecks zu vermindern. Oder sehe ich das falsch ?
Btw: Die Sache mit dem Geld : Es geht mir nicht ums Geld. Wie schon öfter erwähnt habe ich garnicht vor das Buch weiterzulesen. Aber aus anderen Gründen. Die geballte Kritik verstärkt den Entschluss nurnoch.
Aber ich fand das Buch bis dato not bad.
-
Felixxx schrieb:
Aber ich denke es ist doch mal Geschmackssache, ob man std::string oder char array[50] verwendet.
Ist es denn auch Geschmackssache, ob man ein sicheres oder unsicheres Rennauto fährt?
Wenn man schon auf
std::string
verzichtet, dann kann man auch gleich in C programmieren. Denn das wasstd::string
bietet macht C++ aus; wer sich dagegen wehrt, der wehrt sich gegen die Sprache an sich.
-
Felixxx schrieb:
Aber ich denke es ist doch mal Geschmackssache, ob man std::string oder char array[50] verwendet.
Eben nicht. Das eine ist narrensicher, das andere ist fehleranfällig. Das eine ist kurz und elegant, das andere ist umständlich (es gibt ein paar Situationen in denen C-Strings kürzer und elganter sein können, aber dies ist eher die Ausnahme). Das eine ist vom Stil her konsistent zum Rest der Sprache, das andere nicht. Das eine ist etwas mit denen andere C++ Programmierer sich bestens auskennen, das andere nicht. Das eine hat eine intuitive Semantik (überladene Operatoren), das andere nicht. Beim einen wird alles automatisch für einen gemacht, beim anderen muss man selber auf alles aufpassen (und wehe man macht etwas falsch!). Beim einen hat man ohne Kosten die Flexibilität etwas ganz anderes zu machen (wusstest du zum Beispiel, dass man Strings mit int als Basis (anstatt char) haben kann? Das geht sogar mit eigenen Datentypen. Und man kann trotzdem alles so benutzen wie einen normalen std::string), beim anderen nicht.
Deine C-Strings liegen immernoch im speicher und werden sogar verdopelt wenn du nen std::string damit initialiesiert. Das sollte man zumindest wissen um Schpeicherlecks zu vermindern. Oder sehe ich das falsch ?
Das siehst du falsch. Wo du das her hast, kann man sich ja denken
-
Hmm true.
Aber :
Für mich macht es immernoch Sinn bzw. ist es nicht schlimm, auf C-Strings in einem Buch vor std::string einzugehen. Ich möchte nicht nomal wiederholen warum ich denke, dass er das so macht ( auf string äher eingehen ... ) und es so auch durchaus Sinn macht.
Außerdem :
C ist Basis von C++.
Es ist also nicht grausam und programmier-schadend C-Strings als eine Alternative zu std::string zu halten.
-
Das sehe ich falsch ? Was sehe ich falsch ?
Und du hast recht, was die Verwendung von string in komplexen Programmen betrifft, in dem man sehr viel damit rumhantiert.
Aber in Programmen, wo sie eher eine kleine Rolle spielen, kann man ruhig C-String nehmen, da schneller.
-
Felixxx schrieb:
Oder sehe ich das falsch ?
Ja und nein.
Felixxx schrieb:
Deine C-Strings liegen immernoch im speicher und werden sogar verdopelt wenn du nen std::string damit initialiesiert.
Ja. Deswegen mache ich sowas nicht grundsätzlich. Bei mir leben C-Strings und std::string harmonisch nebeneinander. Das sind keine Gegner. Es sind auch nicht Vorgänger und Nachfolger. Manchmal sind C-Strings auch in C++ angemessen. Aber sauselten. Vielleicht so selten, daß es gescheit wäre, sie weit nach std::string zu bringen. Dazu müßte man auch die Beispielprogramme umsortieren und das erste, das argv[] benutzt, nach hinten schieben. So Sachen halt und es wird rund.
Felixxx schrieb:
Das sollte man zumindest wissen um Schpeicherlecks zu vermindern.
Keine Speicherlöcher sichtbar. Welches meinst Du? Ich sehe keins.
-
Es ist in einigen Situationen sogar erforderlich mit C Strings zu arbeiten.
Das betrifft insbesondere in C geschriebene Schnittstellen, wie der WinAPI.Du hast also insofern recht, dass man sich auch mit den C Strings auseinandergesetzt haben sollte. Aber ob es pädagogisch sinnvoll ist zunächst auf diese einzugehen, halte ich für sehr fraglich. Bieten sie doch viel mehr Fallstricke, als
std::string
es tut. Versuch doch mal zwei C Strings mit == zu vergleichen. Das ist für einen Anfänger alles andere als intuitiv, sondern einfach nur frustrierend! So macht programmieren keinen Spaß.Im übrigen versucht man von C Arrays (wenn es anders nicht geht) schnell wieder zu
std::string
zu kommen. Man schreibt sich einfach Wrapper, die diese hässlichen und unsicheren Dinge wegkapseln.Und ob C Basis von C++ ist. Wenn das mal kein Flamewar auslöst.
Und das Argument mit der Geschwindigkeit ist lächerlich. Eine solch zeitkritische Anwendung musst du erst mal programmieren müssen. Sehr unwahrscheinlich.
-
Naja,
der speicher für das char array wird zB nicht automatisch freigegeben das heißt man muss das selbst erldigen.
Aber viele wissen nicht einmal, dass jedesmal wenn du iwo "bla" schreibst eig nen char array erstellt wird.
-
Ja das Argument mit der Zeit ist natürlich etwas schwach
Aber ich meinte, dass man C-Strings in eben solchen Programmen verwendet.
Und das mit == geht natürlich auch nicht. Aber wozu gibts strcmp. Wobei das natürlich wieder umständlicher ist, als bei std::string, wo der Operator schon schön überladen wurde
Trotzdem ...
-
Versuch doch einfach mal mit C Strings ein Programm zu realisieren, welches zwei C Strings einliest und anschließend miteinander verknüpft. Der neu entstandene C String soll dann rückwärts ausgegeben werden.
Damit du weißt, worum es geht. Hier eine mögliche Lösung mit
std::string
:#include <iostream> #include <algorithm> #include <string> #include <iterator> int main() { std::cout << "S1: "; std::string s1; std::getline(std::cin, s1); std::cout << "S2: "; std::string s2; std::getline(std::cin, s2); std::cout << "S3: "; std::string s3 = s1 + s2; std::copy(s3.rbegin(), s3.rend(), std::ostream_iterator<char>(std::cout, "")); return 0; }
Die Frage die du dir danach stellen solltest: Sind C Strings den Aufwand wert?
-
,,,, schrieb:
Es ist in einigen Situationen sogar erforderlich mit C Strings zu arbeiten.
Das betrifft insbesondere in C geschriebene Schnittstellen, wie der WinAPI.Aber nur wenn die API einen veränderbaren Zeiger auf den C-String erwartet (d.h.
char*
). Sonst gibt es ja die Funktionc_str
, die man immer verwenden kann, wenn ein nur-lese-string erwartet wird (d.h.const char*
).
-
Felixxx schrieb:
Naja,
der speicher für das char array wird zB nicht automatisch freigegeben das heißt man muss das selbst erldigen.
Aber viele wissen nicht einmal, dass jedesmal wenn du iwo "bla" schreibst eig nen char array erstellt wird.void foo() { const char tmp[] = "bla"; }
erzeugt also ein speicherleck? ich glaube nicht...
um auf deine frage zu antworten, ob man std::string zusammen mit int, char, ... dem leser "bekannt" machen sollte: kann man - würde ich als autor vrmtl auch tun.
kapitel datentypen oder so und dann fängt man halt an:
ganzzahlen: int
gleitkommazahlen: float
_einzelne_ zeichen: char
zeichenketten("strings"): std::string (erfordert #include <string>)einziges problem ist hier halt, dass man namespaces und includes noch gar nicht wirklich kennt.
stroustrup macht es glaube in seinem (neueren) buch so, dass er ein file hat, was man immer includiert(darin werden sämtliche stl-header included und der namespace std im globalen ausgeleert) und dann kann er einfach schreiben:
zeichenketten: string.C ist Basis von C++
es geht nicht um die syntax. es sind die versch. paradigmen der sprachen
Es ist in einigen Situationen sogar erforderlich mit C Strings zu arbeiten.
Das betrifft insbesondere in C geschriebene Schnittstellen, wie der WinAPI.hatten wir bereits: std::string::c_str
und du willst mir doch nicht erzählen, dass man als anfänger zu allererst die winapi-fkt nutzen muss o.ä.Ja das Argument mit der Zeit ist natürlich etwas schwach
bleiben also noch deine anderen vielen argumente:
- nichts
(wenn der zeit-faktor natürlich eine rolle spielt, dann bring doch mal ein bsp. für so etwas.)
Und das mit == geht natürlich auch nicht. Aber wozu gibts strcmp. Wobei das natürlich wieder umständlicher ist, als bei std::string, wo der Operator schon schön überladen wurde
ja - es gibt eben wieder irgendwo eine funktion, die das kann - aber es ist nicht intuitiv. und noch immer einer der beliebtesten anfängerfehler.
std::copy(s3.rbegin(), s3.rend(), std::ostream_iterator<char>(std::cout, ""));
das nem anfänger zu präsentieren finde ich auch ein wenig.. naja - optimistischbb
-
Felixxx schrieb:
Das sehe ich falsch ? Was sehe ich falsch ?
Das Speicherloch.
Felixxx schrieb:
Naja,
der speicher für das char array wird zB nicht automatisch freigegeben das heißt man muss das selbst erldigen.Umgekehrt wird ein Schuh daraus: Speicher von std::string wird automatisch freigegeben, bei char-Arrays nur wenn man statische benutzt. Üblicherweise tut man dies aber nicht. Benutzt man dynamische Arrays (und dies ist der Normalfall) muss man wie Hölle aufpassen, diese wieder freizugeben. Dies geht sogar so weit, dass man seinen Programmierstil entsprechend anpassen muss - nicht unbedingt zum Besseren. Und richtig lustig wird's mit Exceptions.
Aber viele wissen nicht einmal, dass jedesmal wenn du iwo "bla" schreibst eig nen char array erstellt wird.
Das ist ja auch falsch. Das "Bla" steht dann irgendwo im Datensegment vom Programm. Technisch gesehen ist es ein C-String, aber wo wäre dieses Wissen von irgendeiner Bedeutung?
-
,,,, schrieb:
std::copy(s3.rbegin(), s3.rend(), std::ostream_iterator<char>(std::cout,
Das gefällt mir nicht.
,,,, schrieb:
Die Frage die du dir danach stellen solltest: Sind C Strings den Aufwand wert?
Ja. Da werde ich eine strrev-Funktion schon finden oder im Zweifelsfall ergoogeln oder in 2 Minuten selber schreiben.
Aber gibt's sowas Tolles nicht auch in C++?
Mir widerstrebt es, "den string rückwärts auszugeben" statt "den string umzudrehen und dann auszugeben".
Ich kenne natürlich die Fälle, wo man "rückwärts ausgeben" braucht.
-
#include <iostream> using namespace std; // Das Gönn ich mir :D int main() { cout<<"Lets go ..."<<endl; // JA , hier wirds auch wieder kritik geben ... char carray1[50],carray2[50],carray3[50],addedArray[160]; cout<<"Carray 1 : "; cin.getline(carray1,sizeof(carray1) ); cout<<"Carry 2 : "; cin.getline(carray2,sizeof(carray2) ); cout<<"Carray 3 : "; cin.getline(carray3,sizeof(carray3) ); strcpy(addedArray,carray1); strcat(addedArray,carray2); strcat(addedarray,carray3); cout<<"Added Array: "; for(int i = strlen(addedArray); i>=0; i--) cout<<addedArray[i]; cout<<endl; system("pause"); // Meintwegen auch cin.get(); return 0; }
Joa, schon etwas umständlicher. Auch feste Grössen required. ( Natürlich nicht unbedingt aber wäre bisl weiterer Aufwand )
Strev() ? Nicht ergoogled
Wollte aber jetzt auch nicht extra nach was Sinvollem googeln ...
Hab den C-String auch nicht zwischengespeichert sondern nur ausgegeben. Anderes wars aber auch nicht verlangt !
-
das geht viel schöner:
#include <iostream> #include <iterator> #include <algorithm> int main() { const int max = 255; char s[max]; int len = 0; std::cout << "S1: "; std::cin.getline(s, max); len += std::cin.gcount(); std::cout << "S2: "; std::cin.getline(s+len, max-len); len += std::cin.gcount(); std::cout << "S3: "; std::reverse_copy(s, s+len, std::ostream_iterator<char>(std::cout, "")); return 0; }
-
Trotzdem hast du das sehr schön gemacht. Vorallem die Tatsache, dass es keinen Überlauf geben kann beeindruckt mich durchaus. Ich hätte das jetzt anders erwartet.
Die fixen Größen sind natürlich nicht unbedingt realistisch. Denn man weiß nicht immer, wie groß die zu erwartenen Daten sind und will diese auch nicht einschränken. Entsprechend müsstest du dann mit dynamischem Speicher hantieren und dann wird im Zusammenhang mit C Strings so richtig ekelig.
Fazit: Es ist gut, wenn man sich mit C Strings auskennt, aber dann wird man auch wissen, dass sie gefährlich sein können und entsprechend auf
std::string
umschwenken.
-
C++ Primer kann ich mir kostenlos über 2/3 Monate aus der Bibliothek ausleihen.
kann ich dann "C++ von A bis Z" nacher als Nachschlagewerk nutzen oder soll ich das komplett in den Müll werfen.
Gibt es vielleicht noch ein neueres gutes C++ Buch als den C++ Primer?
-
Danke Felixxx.
Ganz ehrlich der Thread gehört für mich weniger ins C++ Forum. Fakt ist, dass der std::string einfacher in der Verwendung und gleichsam unanfälliger für Fehler ist. Es ist gut den C-String zu kennen, man sollte aber bei der C++ Programmierung darauf nach Möglichkeit verzichten.
Dies führt in der Regel zu Ankerkennung und großer Ehre unter den C++ Anhängern!
-
Thx @ ,,,, Wahres Fazit
Ich versuche jezz mal Hooks zu verstehen
Damit ich mal wieder was spanndendres mache als Konsolen-Crap .
@ HighLigerBiMBam Wofür Danke ? Hab ich wieder irgendwelche Theorieren mit Fehlern bewiesen ? .......