char array vs. string
-
Hoppala, ihr lauert ja regelrecht auf eine Antwort.
Ist natürlich kein Problem, so hab ich ja vor kurzem auch noch verfahren. Aber mir gefällt jetzt die Lösung mit meiner Klasse besser, weil ich jetzt auch noch schöne Operatoren habe wie +=, ==, + und in absehbarer Zeit noch Methoden einbaue um nach nen Teilstring zu suchen und so weiter.
Wenn dir das nicht besser gefällt, dann kannst du dich ja freuen, dass es nach deinem Geschmack schon fertig drin ist.
(Ich bin heute so gemein)
-
Ich weiss. Ich sage nur:
wstringstream x;
x.str().c_str();Ich sage nur: 42.
Mach dich halt lächerlich.
Mach ich doch.
int ist ein primitiver und verdammt gebräuchlicher Datentyp.
Und? type_info auch.
Hast du noch nie ne verdammte Meldung ausgegeben, wo mal ne veränderbare Zahl drin vorkommt?!
Doch.
funktion (meldung + lexical_cast<string>(wert));
@Optimizer:
Warum gibts eine solche Klasse nicht im Standard? Weil jeder unter so ner Addition was anderes versteht. Was heißt denn
"12"+"34"? ist das "1234" oder "46"?Na was wohl? Wenn ich die Zahlen addieren wollen würde, dann würde ich schreiben String x = 12 + 34; und voilà, da haben wirs doch, das funktioniert nämlich auch. Das einzige echte Argument was du gebracht hast, dass man es vielleicht als Hex-Zahl haben will.
@Optimizer:
Was ist mit "1" + 1? "11", "2", 2 oder vielleicht sogar 11? (letzeres ist natürlich Quatsch.)Jo, das man mal einen Text aus ein paar chars und einer Zahl zusammenstückelt, ist natürlich "hinz und kunz".
Irgendwie habe ich den Gebrauch von "hinz und kunz" anders in Errinerung.
Bloß nicht die Klasse leicht bedienbar machen, und sowas essentielles wie ne Verknüpfung mit int und strings einbauen.
Stimmt. Ihne solche Verknüpfungen kann ich nicht mehr leben. Sie geben allem überhaut einen Sinn. Sie sind die Essenz meines Lebens.
-
Teilstrings suchen gibts schon in der Standardlib...
Statt Operatoren zu überladen, fände ich dann aber sowas besser:
string s = format("bla %x %x") << x << y;
Sowas hat ja boost, weiß jetzt nur nicht wie es da umgesetzt ist.
-
Hoppala, ihr lauert ja regelrecht auf eine Antwort.
Ist natürlich kein Problem, so hab ich ja vor kurzem auch noch verfahren. Aber mir gefällt jetzt die Lösung mit meiner Klasse besser, weil ich jetzt auch noch schöne Operatoren habe wie +=, ==, + und in absehbarer Zeit noch Methoden einbaue um nach nen Teilstring zu suchen und so weiter.
Wenn dir das nicht besser gefällt, dann kannst du dich ja freuen, dass es nach deinem Geschmack schon fertig drin ist.Könntest du für micht bitte auch noch ein operator * (deinstring, int) einbauen, der den String mehrfach hintereinander hängt.
Deinstring ergebnis = Deinstring("ABC") * 3;
ergibt also "ABCABCABC".
und ein operator - fände ich auch gut, um Teilstrings zu löschen:
Deinstring("FooBarFooBarBarBarFoo") - "Foo"
-> "BarBarBarBar"
-
Wenn ICH das brauchen würde, würde ich es einbauen, allerdings in Form einer Methode. Ok, ich bin anscheinend echt der einzige, der mal ne Zahl in nen String einfügen will. Dann hat sich das Thema eh erledigt.
@Optimizer:
Was ist mit "1" + 1? "11", "2", 2 oder vielleicht sogar 11? (letzeres ist natürlich Quatsch.)Wovon rede ich die ganze Zeit? Eine Zahl in Text einfügen? Also natürlich "11". Da kann doch jetzt ich nichts dafür, dass du so ein ... äh ... nicht praxisbezogenes Beispiel gewählt hast.
Tut mir leid, die Sachen die ich anspreche, sind Standard in praktisch jeder Programmiersprache. Ich programmiere nebenbei noch Java und habe früher mit VB programmiert und ich habe noch nie ein Forum gesehen, wo so viele Leute nicht wissen, wie man mit Strings umgeht.
Keine Ahnung warum euch das so weh tut, wenn man einfach schreiben kannString x = "Sie haben " + (int)money + " Euro auf dem Konto."
Ach und sogar an euer Krokodil ist gedacht: In Java hat jede Klasse eine toString() Methode und ich kann tatsächlich schreiben:
meinKrokodil = new Krokodil(); String x = "Bla" + meinKrokodil;
Ein Feature, das man nicht nutzen muss. Aber wenigstens mit primitiven Typen sollte man seinen String schon verknüpfen können.
-
Aber es ist nicht schwer, selbst etwas zu bauen, sei es eine operator+ überladung oder eine string cat(const string&,int) funktion.
allerdings bin ich froh, dass mir nicht irgendein komitee eine solch spezielle bedeutung von + aufhetzt, wenn ich mich dazu entscheide, ein operator+(string,int) zu machen, der strings (->nach int konvertiert) addieren kann.
freie wahl.
-
Ist ein
string x = "Sie haben " + lexical_cast<string>(money) + " Euro auf dem Konto."
so viel komplizierter, als ein
String x = "Sie haben " + (int)money + " Euro auf dem Konto."
?
-
herrlado schrieb:
Danke!
Aber was würdet ihr mir empfehlen, als Anfänger zu nutzen? Bin siet ein Paar Monaten dabei.Bisher habe ich immer string benutzt. Also soll ich mit string weitermachen?wie oben gesagt: ja, vergiss aber nicht, dir die char* auch anzuschauen, ohne geht nicht. fahr zweigleisig.
-
Helium schrieb:
Ist ein
string x = "Sie haben " + lexical_cast<string>(money) + " Euro auf dem Konto."
so viel komplizierter, als ein
String x = "Sie haben " + (int)money + " Euro auf dem Konto."
?
Nein, aber unschöner. Ich frage mich nur immer, warum euch das weh tun würde, wenn das Standardmäßig so gemacht wird, dass man gleich ints und floats anhängen kann?
Oder was ist so schlimm daran, sich selber eine Klasse zu schreiben / die bestehende Klasse entsprechend zu erweitern? Das war ja mein Vorschlag.davie schrieb:
Aber es ist nicht schwer, selbst etwas zu bauen, sei es eine operator+ überladung oder eine string cat(const string&,int) funktion.
allerdings bin ich froh, dass mir nicht irgendein komitee eine solch spezielle bedeutung von + aufhetzt, wenn ich mich dazu entscheide, ein operator+(string,int) zu machen, der strings (->nach int konvertiert) addieren kann.
freie wahl.Ach wie schlimm, dann müsstest du halt beim String ne Methode aufrufen, der dir einen int zurückgibt und in die andere Richtung (die sicherlich häufiger gebraucht wird) hast du es automatisch. Aber so wie es jetzt aussieht, geht ja keins von beiden automatisch.
-
Wo wir von Automatismen reden: Hat deine String-Klasse auch einen operator(int)? Gibt's einen Konstruktor Deinstring(int), der nicht explicit ist?
-
Optimizer schrieb:
Oder was ist so schlimm daran, sich selber eine Klasse zu schreiben / die bestehende Klasse entsprechend zu erweitern? Das war ja mein Vorschlag.
Und was ist so schlimm daran zB lexical_cast zu verwenden?
Das Problem mit dem neuschreiben der String-Klasse ist folgendes: es gibt bereits eine standardisierte Klasse die alles kann was du willst (mit Hilfe von lexical_cast) (IMHO sollten kovertierungen sowieso über eine extra funktion laufen - so dass string dann nicht nur int sondern auch Korkodil kann)
-
Ich bin mir nicht sicher, ob ich dich richtig verstehe. Meine Klasse wird von Zeit zu Zeit noch erweitert, im Moment hat sie das:
class String { public: // Konstruktoren: String(); String(const String &source); String(const TCHAR *text); String(const __int32 int32Bit); String(const __int64 int64Bit); String(const bool value); // Destruktor: ~String(); // Gibt einen Zeiger auf den String zurück. TCHAR* pointer(); // Gibt das Zeichen an der aktuellen Position zurück. TCHAR charAt(int position); // Gibt die Länge des Strings zurück. int length(); // Vergleicht zwei Strings. bool equals(const String &other) const; // Operatoren '+=' zum Anhängen: void operator+= (TCHAR *otherString); void operator+= (const String &otherString); void operator+= (__int32 int32Bit); void operator+= (__int64 int64Bit); void operator+= (bool value); // Operatoren '=' zum Zuweisen: void operator= (const String &otherString); void operator= (const TCHAR *text); void operator= (__int32 int32Bit); void operator= (__int64 int64Bit); void operator= (bool value); private: TCHAR* data; inline void copyStringData(const String &source); } inline const String operator+(const String &s1, const TCHAR *s2)[...] inline const String operator+(const String &s1, __int32 s2)[...] inline const String operator+(const String &s1, __int64 s2)[...] inline const String operator+(const String &s1, bool s2)[...] inline const String operator+(const String &s1, const String &s2)[...]
(Fließkomma-Zahlen folgen noch)
Wenn du meinst, es fehlt was wichtiges, dann nur raus damit.
-
Optimizer schrieb:
Aber nicht wahr, Hume, es ist ja so unglaublich falsch, eine anständige Klasse zu coden und damit das Problem ein für alle mal aus der Welt zu schaffen.
Kannst du lesen oder bist du einfach nur daran interessiert rumzumaulen?
Ich habe nirgends bezweifelt, dass es nicht Situationen gibt, in denen eine eigene Stringklasse sinnvoll sein kann. Ich schrieb "generell" im Sinne von "im Allgemeinen". Es ist einfach eine Verschwendung von Programmierzeit, wenn man grundlos das Rad neu erfindet. Wer eine eigene Stringklasse schreibt (und diese auch noch in seinen Interfaces verwedent), nur weil er eine Zahl bequem an einen String hängen will (dabei alle besseren Möglichkeiten ignoriert), der hat schlicht und einfach keine Ahnung und sollte lieber nur zu Hause in seinem Keller nur für sich programmieren. Punkt. So und jetzt kannst du von mir aus weiter rumheulen.
HumeSikkins schrieb:
Zitat:
Ich denke die große Portabilität ist der größte Vorteil von good ol' char-Arrays.Helium schrieb:
Hä?
Was willst du mir damit sagen? Habe ich das falsche Wort verwendet? Was ich sagen wollte, hat Irgendwer in seinem Beitrag bereits angedeutet. const char* sind einfach nach wie vor der kleinste gemeinsame Nenner und ich bevorzuge aus diesem Grund in Schnittstellen von Komponenten die häufig (wieder)verwendet werden immer const char*. Aber vielleicht kannst du ja noch mal etwas ausführlicher deine Probleme mit meiner Antwort darlegen.
PS:
Desweiteren halte ich std::string für eine ziemlich furchtbare Stringklasse (der Hauptgrund dafür wurde von Bashar bereits angesprochen). Sie ist aber standard und das ist der ganz entscheidene Vorteil.
-
und wie machst du
string std_greet("hello"), place("world"), newline("\n"); string greet = std_greet += " " + place += "!" + newline;
-
@Optimizer
Wenn ich mir deine Klasse so anschaue, denke ich, du solltest besser bei Java bleiben.Allein die Operatorüberladung der Marke willkür treibt einem, der mal Scott Meyers gelesen hat Tränen in die Augen.
Wenn du doch bei C++ bleiben möchtest, solltest du auf jeden Fall mal "Effective C++" zur Hand nehmen.
-
Und es ist jetz intuitiv charAt statt des in C++ üblichen operator[] zu verwenden? und es ist intuitiv die Methode equals zu verwenden, statt des in C++ üblichen operator ==?
Was willst du mir damit sagen? Habe ich das falsche Wort verwendet? Was ich sagen wollte, hat Irgendwer in seinem Beitrag bereits angedeutet. const char* sind einfach nach wie vor der kleinste gemeinsame Nenner und ich bevorzuge aus diesem Grund in Schnittstellen von Komponenten die häufig (wieder)verwendet werden immer const char*. Aber vielleicht kannst du ja noch mal etwas ausführlicher deine Probleme mit meiner Antwort darlegen.
Genau das meinte ich: In wie fern Portabler? Man braucht char* für Schnittstellen, was es aber doch nicht Portabler macht.
-
HumeSikkins schrieb:
Optimizer schrieb:
Aber nicht wahr, Hume, es ist ja so unglaublich falsch, eine anständige Klasse zu coden und damit das Problem ein für alle mal aus der Welt zu schaffen.
Kannst du lesen oder bist du einfach nur daran interessiert rumzumaulen? Ich schrieb "generell" im Sinne von "im Allgemeinen".
Super, und ich finde, generell sollte jeder mal ein String-Klasse schreiben. Genauso geile Begründung.
So wie du es gesagt hast, ist es das schlimmste was man machen kann, wenn man einmal in seinem Leben so ne Klasse schreibt und die immer wieder verwenden kann.HumeSikkins schrieb:
@Optimizer
Wenn ich mir deine Klasse so anschaue, denke ich, du solltest besser bei Java bleiben.Allein die Operatorüberladung der Marke willkür treibt einem, der mal Scott Meyers gelesen hat Tränen in die Augen.
Wenn du doch bei C++ bleiben möchtest, solltest du auf jeden Fall mal "Effective C++" zur Hand nehmen.
Mach einen besseren Vorschlag. Ich habe weder gesagt, dass meine Klasse perfekt ist, noch dass ich übermäßig stolz auf sie bin. Ich habe sie geschrieben, um bequem Dateien in einer Schleife laden zu können (siehe weiter oben).
Und wenn du was zu verbessern hast, dann lass es doch bitte hören.davie schrieb:
und wie machst du
string std_greet("hello"), place("world"), newline("\n"); string greet = std_greet += " " + place += "!" + newline;
Was beabsichtigst du genau? Vielleicht meinst du ja:
String greet("hello"), place("world"), newLine("\n"); String bla = greet + place + newLine;
Helium schrieb:
Und es ist jetz intuitiv charAt statt des in C++ üblichen operator[] zu verwenden? und es ist intuitiv die Methode equals zu verwenden, statt des in C++ üblichen operator ==?
charAt() finde ich jetzt ziemlich intuitiv. Den Operator '==' wollte ich auch noch überladen, der soll dann die Methode equals() aufrufen. Dagegen ist ja nichts einzuwenden.
-
Ich persönlich sehe auch keinen Grund sich die Arbeit zu machen eine neue stringklasse zu schreiben.
Ich wüsste auch nicht was ich davon habe ? Ne menge Zeitverlust. Und das in der ohnehin knapp bemessenen Zeit. Lieber erst anschauen wenn man es
wirklich braucht.Wie bereits vorgestellt, überladen von operator<< als template hilft weiter. Ich selbst habe damit eine ini Klasse geschrieben um allerlei Datentypen wegschreiben zu können. Sollte man dann mal an einen Punkt kommen wo der Profiler aufheult vor schmerz kann man immernoch den operator für einen speziellen Typen spezialisieren und flott integrieren.
Ich denke der Standard liefert massig Möglichkeiten. Ansonsten gibt es ja bereits erstellte Libs wie looki oder boost. Bevor ich also ewigkeiten in eine neue Klasse stecke bring ich lieber mal boost ans laufen.
Zu der Sache:
foo(char *);
und string übergeben:
Ich würde hier keinen Buffer kopieren. Meist kann man sich sicher sein das der String nur gelesen wird. Bevor ich also kopiere schliesse ich mich dem unsauberen design an
und verspreche dem Compiler mit einem const_cast<char*>(string.c_str()); das nichts passiert. Nur in seltenen Fällen kopiere ich um.Ich denke jeder zieht erst mal den Standard vor . Erst wenn der Profiler den flaschenhals bei einer Standardmethode aufweisst macht man sich die mühe zu suchen.
(Bei einer Ini Klasse ist z.B. i.d.r. nichts Zeitkritisches vorhanden...)Letzendlich darf man nicht vergessen das Entwicklungszeit mehr Kostet als Rechenzeit. Es bringt also nichts wenn man die schnellste Klasse der Welt hat, wenn keiner die Schnittstelle kennt. In der realität läuft vieles nicht ideal weil es einfach zu teuer wäre.
-
Ich stimme dir in den meisten Punkten zu. Ich habe die Klasse auch nicht zum Spaß geschrieben, sondern ich fand es einfach nur ZU arm, dass ich nicht mal nen einfachen Text mit variablen Werten darin erstellen konnte. Ich habe mich einfach maßlos über die Standard-stringklasse geärgert.
Da meine Ausgabe nicht über cout funktioniert, sondern über Direct3D, war ich gezwungen, mir eine Möglichkeit zu suchen, ein passendes char-Array zusammenzubasteln.
Ich habe mir dann eine ganze Weile mit stringstreams geholfen, aber irgendwann war mir das Ganze einfach zu hässlich.
Zur Entwicklungszeit möchte ich sagen, dass das Ganze nicht länger als (insgesamt!) 5-6 Stunden gedauert hat und diese Zeit gewiss nicht verschwendet war.Mir wäre es auch lieber gewesen, std::string würde wenigstens so einfache Verknüpfungen (die trotz aller gegenteiligen Behauptungen kein hoch spezieller Wunsch meinerseits sind) unterstützen. Dann hätte ich mir den Aufwand auch sparen können, wie in anderen Programmiersprachen. Aber ja, es könnte ja sein, dass jemand bei <text> + <zahl> dann ne Verknüpfung <(zahl)text> + <zahl> = <zahl> haben möchte - lol.
Das könnt ihr sehen wie ihr wollt, ich rate lediglich, std::string zu benutzen und wenn das nicht reicht, eine eigene Klasse zu schreiben (das war der Ausgangspunkt der Diskussion). Das ist ein einmaliger Aufwand.
-
Optimizer schrieb:
Da meine Ausgabe nicht über cout funktioniert, sondern über Direct3D, war ich gezwungen, mir eine Möglichkeit zu suchen, ein passendes char-Array zusammenzubasteln.
Alternativ könnte man auch einfach einen Wrapper um die dumme DirectX-Funktion basteln.