C-Strings vergleichen



  • 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 Funktion c_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 - optimistisch 😉

    bb


  • Mod

    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 ? .......



  • Nein Felix, ich habe mir beim lesen nur gedacht, dass bestimmt keine C-String Antwort folgt 😉

    👍



  • Hä ich komme nicht ganz mit 😛 Die "Aufgabenstellung" war ja genau das mit C-Strings zu machen ? Oder was meinste jetzt ?



  • Ich fand ja auch den C-String Konter gut 🙂



  • @ skilled Ich habe einige Argumente genannt ... schau doch nochmal durch.

    Das mit dem Speicherleck hast du einfach falsch verstanden, auch das nochmal durchschauen. Selbiges gilt für die Frage nach der Bedeutung.



  • Sobald man exceptionsicheren Code schreiben möchte, kann man dynamisch allokierte C-Strings quasi nicht mehr verwenden - dafür braucht man einfach RAII.

    Das Problem an dem Wolf-Buch, ist dass es kein idiomatisches C++ lehrt, sondern C mit Klassen. Das manifestiert sich dann an solchen Beispielen wie std::string contra Char-Array.

    C++ ist auf der Abstraktionsleiter nochmal einige Stufen über C und das sollte in einem Lehrbuch für Anfänger auch so gelehrt werden, vor allem da die Abstraktion dem Programmierer das Leben erleichtert - bei minimalen Performanceverlust.
    Und genau das macht den "C++ Primer" zu einem guten und "C++ von A bin Z" zu einem schlechten Buch.



  • Oberon_0 schrieb:

    ,,,, 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 Funktion c_str , die man immer verwenden kann, wenn ein nur-lese-string erwartet wird (d.h. const char* ).

    Nicht mal dann. Es gibt std::vector<char> und sonst halt noch std::tr1::array . Ich empfehle auch wegen RAII dringend std::vector<char> zu verwenden.

    @Felixxx,
    Wenn du lieber schöne GUIs haben willst oder irgendwelche kleine Tools basteln möchtest, dann ist vielleicht C++ die falsche Sprache? Auf Windows kann man dafür zum Beispiel C# empfehlen. Ansonsten ist wohl durchaus auch Java eine Empfehlung wert. Sprachen haben nunmal auch ihre Stärken und Schwächen bei den Einsatzzwecken. Für die GUI Programmierung oder der schnellen Verwirklichung von kleinen Tools ist C++ nicht gerade optimal.

    Grüssli



  • Natürlich stammen C-String aus C, aber man benutzt sie trotzdem sehr häufig in C++.

    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.

    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.

    Das ist schlicht und ergreifend Blödsinn. Und dann deine zusammengebastelte Lösung, die nur funktioniert, wenn der Anwender freundlicherweise weniger als 50 Zeichen schreibt 🙄

    Du sagst, dass man C-Strings verwenden kann, wenn, ja wenn man alles Dahinterliegende und alle Funktionen mit ihren Fallstricken verstanden hat. Das stimmt, ist aber bei dir und anderen Anfängern offensichtlich nicht der Fall. Warum genau soll std::string nun auf Seite 695 hinter OOP, Templates, der STL und Exception-Handling (!!!) stehen, während C-Strings am Anfang des Buchs behandelt werden?

    Edit: Auf RAII bist du noch gar nicht eingegangen, aber wahrscheinlich fliegt bei J. W. erst auf Seite 662 die erste Exception und er macht auch nicht klar, wofür man RAII sonst gebrauchen könnte 🙄


Anmelden zum Antworten