WEBCGI-Projekt | Verbesserungsvorschläge


  • Administrator

    Im Header <string> wird eine freie Funktion mit dem Namen std::getline definiert:
    http://www.cplusplus.com/reference/string/getline.html

    Die könnte hilfreich sein 😉

    Grüssli



  • Habe ich auch gerade gefunden,
    trotzdem vielen Dank, warst sehr hilfreich! 🙂

    Ist mein Programm denn jetzt in C++, oder immernoch C?

    Mit freundlichen Grüßen
    Kevin


  • Administrator

    root2k schrieb:

    Ist mein Programm denn jetzt in C++, oder immernoch C?

    Jetzt ist glaub ich alles C++, soweit ich das erkennen kann. Und nun gebe ich auch gerne ein paar Ratschläge 🙂

    #include <string>
    #include <iostream>
    
    // using namespace std;
    // Ich würde mit dem hier vorsichtig umgehen.
    // Hier kein Problem, aber nie damit in einen Header,
    // und daran denken, dass man damit Namenskonflikte
    // hervorrufen kann.
    
    // Ich nehme nun die Variablen in englisch, klingt irgendwie
    // besser mit all den englischen Schlüsselwörter :)
    
    // Deklaration (auch mehr einfach aus Stilgründen):
    std::string replace(
      std::string const& text,
      std::string const& searchTerm,
      std::string const& replacement);
    
    // Die konstanten Referenzen sind aber empfehlenswert.
    // So wird nicht eine Kopie gemacht, sondern mit dem gleichen
    // Objekt gearbeitet, welches von Aussen kommt. Es ist allerdings
    // garantiert, dass dieses Objekt nicht verändert wird.
    
    int main()
    {
      std::cout << "Text:\t";
    
      std::string text; // In C++ kann man eine Variable auch erst dann
                        // deklarieren, wenn man sie braucht.
      std::getline(std::cin, text);
    
      std::cout << "Suchwort:\t";
    
      std::string searchTerm;
      std::getline(std::cin, searchTerm);
    
      std::cout << "Ersatzwort:\t";
    
      std::string replacement;
      std::getline(std::cin, replacement);
    
      std::cout << replace(text, searchTerm, replacement)
                << '\n'
                << std::endl;
    
      // std::endl fügt nicht nur eine neue Linie ein,
      // sondern führt auch noch ein flush durch.
      // Deshalb wurde das erste std::endl durch ein '\n',
      // bzw. Linefeed, ersetzt.
    
      return 0;
      // return 0 ist bei der main Funktion nicht unbedingt nötig.
    }
    
    std::string replace(
      std::string const& text,
      std::string const& searchTerm,
      std::string const& replacement)
    {
      // Kopie von text erstellen, da wir auf diesem nicht arbeiten können.
      // Es ist ja eine konstante Referenz.
      std::string result = text;
    
      // Wir verändern result und geben es danach zurück.
      return result.replace(
                      text.find(searchTerm),
                      searchTerm.length(),
                      replacement);
    }
    

    So wird übrigens nur das erste Vorkommen von searchTerm ersetzt. Was dein ursprünglicher Code allerdings auch gemacht hat. Nur ist das auch gewollt? Sonst müsstest du es halt in einer Schlaufe durchlaufen lassen.

    Grüssli



  • Wooooow!

    Danke für deine Tipps, ich denke die stilvolle Programmierung ist ein neuer Weg bzw. eine neue Herausforderung für mich, die ich mir auf jeden Fall aneignen sollte. Wir haben es leider nicht anders beigebracht bekommen, auch in meinem C++ Buch steht es nicht anders 😞 Kannst du mir eventuell ein gutes Buch empfehlen, welches ein wenig Stil in die Sache bringt?

    Vielen Dank!

    Kevin


  • Administrator

    root2k schrieb:

    ...

    Stil ist eine ganz eigene Sache, deswegen habe ich es auch gekennzeichnet, da es eher Nebensächlich ist. Es gibt nicht DEN Stil, im Gegenteil, alle sind anderer Meinung, was den richtigen Stil betrifft. Und wenn man darüber anfängt zu diskutieren, werfen sich die Leute am Ende Granaten an die Köpfe 🙂

    Grundsätzlich denke ich, kann man ein paar Grundpunkte nennen:
    1. Dein Stil sollte einheitlich sein.
    2. Den Code nach Scopes einrücken.
    3. Eine Zeilenbreite zwischen 80 - 120 Zeichen anvisieren.
    4. Der Stil muss für dich oder dein Team stimmen. Er sollte die Lesbarkeit unterstützen. Ein guter Stil hast du meiner Meinung nach dann, wenn du ein Projekt während einem Jahr auf die Seite legst und danach dich leicht wieder in den Code einarbeiten kannst, da dein Code gut strukturiert ist.
    5. Ein Stil entwickelt sich über die Zeit und man sollte sich nicht scheuen, seinen Stil mal etwas anzupassen und/oder verändern.

    Ein Buch zu C++ Stil gibt es in diesem Sinne glaube ich nicht. Aber ich glaube dir würde so oder so ein C++ Buch für die Grundlagen gut tun. Für Grundlagen werden hier oft die folgenden zwei empfohlen:
    - C++ Primer
    - Thinking in C++ 1 & 2

    Grüssli



  • Hallo nochmal und danke,

    eine Frage habe ich da noch - wie schaffe ich es, eine Fehlermeldung auszugeben, wenn das Suchwort nicht gefunden wurde? Im Moment beendet er das Programm dann einfach...

    Probiert habe ich schon folgendes...

    std::string replace(
      std::string const& text,
      std::string const& searchTerm,
      std::string const& replacement)
    {
      std::string result = text;
      std::string errormsg = "Das gesuchte Zeichenfragment wurde nicht gefunden.";
    
      if ( text.find(searchTerm) == NULL ) return errormsg;
    
      return result.replace(
                      text.find(searchTerm),
                      searchTerm.length(),
                      replacement);
    }
    

    Doch auch hier wird das Programm einfach beendet. Was gibt text.find(searchTerm) == NULL aus, wenn nichts gefunden wurde?

    MfG, Kevin



  • Du solltest dich mit den Funktionen, die du verwendest, ein wenig vertraut machen (z.B. hier). 😉

    Du musst nämlich nicht auf NULL prüfen... Ausserdem solltest du find() besser nicht zwei Mal aufrufen, da es dann nochmals von vorne mit O(n) im String sucht.

    Um einen Fehler kennzuzeichnen, gibt es in C++ verschiedene Möglichkeiten. Entweder du handhabst ihn gleich lokal, d.h. gibst eine Fehlermeldung aus und erwartest nochmals eine Eingabe (durch eine Schleife, die du erst bei gefundenem Eintrag beendest). Oder du verschachtelst das Ganze in eine Funktion und prüfst den Rückgabewert. Oder du verwendest Exceptions, die du dann irgendwo fangen musst.



  • std::string replace(
      std::string const& text,
      std::string const& searchTerm,
      std::string const& replacement)
    {
      std::string result = text;
    
      std::size_t errorchk = text.find(searchTerm);
    
      if ( errorchk == std::string::npos )
         return "Das gesuchte Zeichenfragment wurde nicht gefunden.";
    
      return result.replace(
                      errorchk,
                      searchTerm.length(),
                      replacement);
    }
    

    Habs jetzt so gelöst, denkst du das geht in Ordnung?


  • Administrator

    root2k schrieb:

    Habs jetzt so gelöst, denkst du das geht in Ordnung?

    Die Lösung ist eher schlecht. Man erwartet im Rückgabewert nicht eine Fehlermeldung, sondern das Resultat. Zudem ist es schwer diesen Rückgabewert zu prüfen, ob es nun einen Fehler gab. Ich persönlich würde gleich die Funktionalität von std::string::replace ausnutzen. Wenn std::string::find ein std::string::npos zurückliefert und man dieses an std::string::replace übergibt, dann wird eine std::out_of_range Exception geworfen. Dies kannst du in der main abfangen und entsprechend darauf reagieren.

    // replace wie ich es aufgezeigt hatte
    
    int main()
    {
      // ... bekannter Code
    
      try
      {
        std::cout << replace(text, searchTerm, replacement)
                  << '\n'
                  << std::endl;
      }
      catch(std::out_of_range&)
      {
        // Sinnvolle Fehlermeldung ...
        std::cerr << "!!!FEHLER; FEHLER; FEHLER!!!" << std::endl;
    
        // SINNVOLLE! :)
      }
    
      return 0;
    }
    

    std::cerr ist im übrigen die Ausgabe für Fehlermeldungen. Dies geht an einen eigenen Puffer, welcher zum Teil mit dem von std::cout übereinstimmt. Wenn man die Ausgabe allerdings auf der Konsole umleitet, dann ist es gut möglich, dass das Zeug von std::cerr auf der Konsole erscheint, std::cout allerdings umgeleitet wird:
    http://www.cplusplus.com/reference/iostream/cerr.html
    http://www.cplusplus.com/reference/iostream/cout.html

    Grüssli



  • Schönen Dank für eure schnellen Antworten,

    habe das jetzt mal so gemacht, jedoch funktioniert das Kompilieren nicht...

    #include <string>
    #include <iostream>
    
    std::string replace(
      std::string const& text,
      std::string const& searchTerm,
      std::string const& replacement);
    
    int main()
    {
      std::cout << "Text:\t";
      std::string text;
      std::getline(std::cin, text);
    
      std::cout << "Suchwort:\t";
      std::string searchTerm;
      std::getline(std::cin, searchTerm);
    
      std::cout << "Ersatzwort:\t";
      std::string replacement;
      std::getline(std::cin, replacement);
    
      try
      {
        std::cout << replace(text, searchTerm, replacement)
                  << '\n'
                  << std::endl;
      }
      catch(std::out_of_range&)
      {
        std::cerr << searchTerm
                  << " wurde leider nicht im Text gefunden."
                  << std::endl;
      }
    
      system("PAUSE");
      return 0;
    }
    
    std::string replace(
      std::string const& text,
      std::string const& searchTerm,
      std::string const& replacement)
    {
      std::string result = text;
    
      return result.replace(
                      text.find(searchTerm),
                      searchTerm.length(),
                      replacement);
    }
    

    Compiler: Bloodshed Dev-C++

    E:\Programme\Dev-Cpp\main.cpp In function int main()': 30 E:\\Programme\\Dev-Cpp\\main.cppstd::out_of_range' has not been declared
    30 E:\Programme\Dev-Cpp\main.cpp invalid catch parameter
    E:\Programme\Dev-Cpp\Makefile.win [Build Error] [main.o] Error 1



  • Okay, das hat sich erledigt, in der Referenz steht, dass folgende Bibliothek eingebunden werden muss:

    #include <stdexcept>
    

    out_of_range - C++ Reference

    Danach hat es funktioniert... Vielen Dank nochmal! Sieht so sehr ordentlich aus


  • Administrator

    root2k schrieb:

    Compiler: Bloodshed Dev-C++

    Wenn ich noch einen Tipp geben darf. Wirf dieses Ding weg. Es gilt als veraltet und wird zudem nicht mehr weiterentwickelt. MAn sollte sich also davon lösen. Gratis C++ IDEs gibt es auch aktuellere:
    - Microsoft Visual Studio 2008 Express (ja, ist wirklich gratis! Und auf Windows sehr zu empfehlen.)
    - Code::Blocks - Platformunabhängig, kombinierbar mit gcc (g++ & gdb)

    root2k schrieb:

    Okay, das hat sich erledigt, in der Referenz steht, dass folgende Bibliothek eingebunden werden muss:

    Das nennt man übrigens nicht eine Bibliothek, sondern einen Header. Der Header gehört zur Standardbibliothek. Also eine Bibliothek ist immer eine Sammlung von Funktionen, Klassen usw., während ein Header Teil einer Bibliothek ist.

    Grüssli



  • Header, nicht Bibliothek. Okay, das kann ich mir merken. 🕶 😉

    Alles klar, hab Dev-C++ mal deinstalliert und im Gegenzug Microsoft Visual Studio 2008 Express heruntergeladen. Danke für den Tipp 👍

    MfG, Kevin



  • Dravere schrieb:

    Also eine Bibliothek ist immer eine Sammlung von Funktionen, Klassen usw., während ein Header Teil einer Bibliothek ist.

    Muss nicht sein. 😉
    Ein/mehrere Header kann/können sehr wohl eine ganze Bibliothek sein. (ist es meistens natürlich nicht so, dass sonst nichts migeliefert wird, aber so endgültige würde ich das nicht sagen)



  • Vielen Dank euch nochmal... Die Ersetzen-Funktion klappt einwandfrei. Leider darf ich momentan keine String-Klasse benutzen, da wir noch keine OOP gemacht haben und da erst noch zu kommen.

    Funktioniert aber trotzdem und ich bin den anderen ein wenig voraus 🙂

    Jetzt kommt das nächste Problem... Ich soll einen Parser schreiben, der Hexcode in Sonderzeichen rückwandelt... Der vom Benutzer eingegebene Quelltext hat ja Sonderzeichen. Diese werden aber bei der Übertragung in Hexcode umgewandelt ... z.B. das Ausrufezeichen "!" wird zu "%21" usw...

    Folgendes habe ich mal probiert (entschuldigt den unglaublich schlecht strukturierten Code, das mache ich immer nachdem alles funktioniert^^)

    #include <iostream>
    #include <string>
    #include <iomanip>
    #include <stdio.h>
    #include <stdlib.h>
    
    char hexToAscii(const char* code);
    char* changeText (char* text);
    
    int main()
    {
    	char* text = "Aber hallo%3f Das ist ja gut zu wissen%21";
    
    	std::cout		<< changeText(text)
    					<< "\n"
    					<< std::endl;
    }
    
    char * changeText (char * text)
    {
    	int i = 0, j = 0;
    	int searchResLen = 0;
    	int textLen = strlen(text);
    	char * searchRes;
    	char * newText = new char [textLen];
    
    	searchRes = strstr(text, "%");
    	searchResLen = strlen(searchRes);
    
    	for (; text[j] != NULL; i++, j++)
    	{
    		if (j == textLen-searchResLen)
    		{
    			newText[i] = hexToAscii(searchRes);
    			j += 2;
    		}
    		else
    		{
    			newText[i] = text[j];
    		}
    	}
    
    	newText[i] = '\0';
    
    	return newText;
    }
    
    char hexToAscii(const char* code)
    {
    	char hex[5], *stop;
    	hex[0] = '0';
    	hex[1] = 'x';
    	hex[2] = code[1];
    	hex[3] = code[2];
    	hex[4] = 0;
    
    	return strtol(hex, &stop, 16);
    }
    

    Ausgabe: Aber hallo? Das ist ja gut zu wissen%21

    Die Funktion hexToAscii bekommt von der Funktion changeText das Suchergebnis von strstr(text, "%") und gibt das hex-Array an die Funktion strtol weiter, welche dann das Sonderzeichen rückliefert.

    Das Programm funktioniert nun aber nur bis zum ersten Sonderzeichen. Danach nicht mehr... ich weiß warum es nicht funktioniert (ich müsste ja mehrmals Suchergebnisse haben), aber ich habe keine Ahnung wie ich es machen soll? Kann mir vielleicht jemand einleuchten?

    Danke schonmal
    der Kev


  • Administrator

    1. Neues Problem -> Neuer Thread
    Das ist auch für dich sinnvoll. Gibt viele Leute, welche ab einem gewissen Zeitpunkt in einem grössen Thread nicht mehr unbedingt reinschauen. Zudem ist es eine besser Ordnung, auch wenn jemand nach einem Problem sucht.
    2. Keine String-Klasse benutzen, kein OOP? Ok, ich versteh schon. Ein Lehrer, welcher seinen Schülern C with Classes als C++ verkauft. In C++ kann man völlig unabhängig von C Programmieren. Um C++ zu beherrschen, muss man nicht C verstehen. Grundsätzlich sind es unabhängig Sprachen. Aber naja, wir sind uns in dem Forum ja daran gewöhnt, dass wir immer wieder von solchen Lehrern hören. Die sind leider Standard ... Fortbildung ist halt immer so eine Sache bei den Leuten.
    3. Zu deinem Problem. Alles was du eigentlich machen müsstest ist, dass du changeText mehrmals aufrufst, bis alle Zeichen ersetzt sind. Du könntest auch sowas intern machen, also in changeText selber, in dem du immer wieder nach dem Prozentzeichen suchst, die Umwandlung machst usw., bis es kein Prozentzeichen mehr findet. Du solltest zudem noch dein Speicherleck schliessen. In der Funktion wird Speicher über new reserviert und nirgends per delete freigegeben.
    4. Die Leute im Forum werden mich womöglich lynchen. Ich finde aber du hast schon Initiative gezeigt und ich hatte gerade Lust, dazu was zu schreiben oder zusammenzustellen. Es ist nicht gerade ausserordentlich toll, da ich nicht so der C Programmierer bin, aber ich denke es dürfte interessant für dich sein:

    //#include <string>   -> Du benutzt ja keine C++ Strings.
    #include <iostream>
    //#include <iomanip>  -> brauchst du doch gar nicht.
    //                       std::endl ist in <iostream> drin
    //#include <stdio.h>  -> falsch, in C++ ist es <cstdio>
    //                       du benötigst es aber gar nicht.
    //#include <stdlib.h> -> falsch, in C++ ist es <cstdlib>
    #include <cstdlib>
    #include <cstring> // -> Um mit C-Strings zu arbeiten.
    #include <cassert> // -> Im Debugmodus kann man damit
    //                       Sicherheitsprüfungen durchführen.
    
    // Kopf bleibt gleich.
    char hexToAscii(char const* code);
    
    // Den Text übergibt man als konstant, er soll in der Funktion
    // schliesslich nicht verändert werden, sondern wird in einen
    // neuen Puffer kopiert.
    // Um Speicherlecks zu verhindern, muss der Anwender der
    // Funktion einen genügend grossen Speicherblock übergeben.
    // Dieser Puffer wird an dest übergeben.
    void changeText(char* dest, char const* text);
    
    int main()
    { 
    	// Man sollte ein Zeiger auf ein String-Literal
    	// als ein Zeiger auf konstanten Inhalt deklarieren.
    	// Es ist nämlich auch der Fall.
    	// Dass es anders geht, liegt nur an einer rückwärts-
    	// kompatibilität zu C.
    	char const* text = "Aber hallo%3f Das ist ja gut zu wissen%21";
    
    	// Wir erstellen uns nun ausserhalb Speicher,
    	// damit wir ihn auch wieder sauber aufräumen können.
    	// Nicht vergessen, zu dem new kommt ein delete.
    	// Der neue Text wird sicher kürzer oder gleichlang sein
    	// wie der alte Text. Also definieren wir einen
    	// Puffer, mit gleicher Grösse.
    	// strlen zählt die Null-Terminierung nicht mit,
    	// deshalb zählen wir noch eins dazu.
    	// Dies ist nötig, falls es keine zu ersetzenden
    	// Hexadezimalzahlen hat. Es gäbe es einen Überlauf
    	// mit undefiniertem Verhalten.
    	char* buffer = new char[strlen(text) + 1];
    
    	// Text wird geändert und in buffer geschrieben.
    	changeText(buffer, text);
    
    	// Der Puffer wird ausgegeben. changeText hat eine
    	// terminierende 0 reingeschrieben, wodurch wir
    	// den Puffer als C-String behandeln können.
    	std::cout << buffer << std::endl;
    
    	delete[] buffer; // <- Das wichtige Delete, welches
    	                 // vorhin fehlte.
    }
    
    // Zu den Funktionen :)
    
    void changeText(char* dest, char const* text)
    {
    	// <cassert> wird hier z.B. verwendet.
    	// Man hat ein Makro assert, welches etwas prüft
    	// und wenn es den Wert false ergibt, bricht das Programm ab.
    	// Diese Prüfung wird nur im Debugmodus durchgeführt.
    	assert(0 != dest && 0 != text);
    
    	// Es wird also geprüft,
    	// ob beide Zeiger keine Nullzeiger sind.
    	// Man könnte hier durchaus noch mehr Prüfungen machen,
    	// bzw. auch im Verlauf der Funktion.
    
    	// Wir müssen nun also kopieren und wenn wir
    	// ein '%' finden, müssen wir entsprechend dieses
    	// Zeichen ignorieren und die nächsten zwei Buchstaben
    	// als Hexadezimalziffern interpretieren. Richtig?
    
    	// Dies machen wir so lange, bis wir am Ende von text
    	// angelangt sind. Also das null terminierende Zeichen
    	// erreichen.
    
    	// Ich gebe dies nun explizit in der Bedingung an,
    	// damit man es gut sieht. Gründsätzlich würde aber auch
    	// ein *text reichen. '\0' entspricht dem Wert 0, was
    	// als false interpretiert würde. Alles andere als 0
    	// ist in C++ true.
    	while('\0' != *text)
    	{
    		// Hexadezimalziffer?
    		if('%' == *text)
    		{
    			// Ja, dann müssen wir übersetzen.
    
    			// Zuerst gehen wir eine Stelle weiter.
    			++text;
    
    			// Hier ist nun die erste Hexadezimalziffer.
    			// Wir übergeben es an deine Funktion und
    			// speichern das Resultat in die aktuelle
    			// Stelle von dest.
    			*dest = hexToAscii(text);
    
    			// text muss nun um eine weitere Stelle
    			// nach vorne geschoben werden.
    			// Die letzte Hexadezimalziffer, wird am
    			// Ende der Schleife noch übersprungen.
    			++text;
    		}
    		else
    		{
    			// Nein, also kopieren wir nur.
    			*dest = *text;
    		}
    
    		// Die beiden Zeiger um eine Stelle weiterschieben.
    		++text;
    		++dest;
    	}
    
    	// Wir fügen noch eine terminierende 0 beim Puffer ein.
    	*dest = '\0';
    
    	// Fertig.
    	// Gemerkt? Wir haben keine zusätzlichen Variablen benötigt.
    	// Nicht mal Funktionen aus der C-Bibliothek. Oder nur indirekt.
    }
    
    char hexToAscii(const char* code)
    { 
    	// Nur aus Sicherheit ein assert.
    	assert(0 != code);
    
    	// Nun, diese Funktion ändere ich ein wenig.
    	// Am liebsten würde ich die C++ Konvertierung verwenden,
    	// aber dann wird sicher wieder gemotzt, dass es OOP ist.
    	// Dann verwende ich eben die C Möglichkeiten.
    
    	// Dazu ist dein Code eigentlich schon ganz gut.
    	// Allerdings ist das 0x zu begin optional, da über die
    	// Basis 16 schon angegeben wird, dass Hexadezimalziffern
    	// gemeint sind. Daher können wir das weglassen.
    	// Auch ist der zweite Parameter von strtol optional.
    	// Ein NULL reicht dort völlig. Steht übrigens alles
    	// in der Referenz, welche du auch schon benutzt hast ;)
    
    	// Wir benutzen zudem die sofortige Initialisierung.
    	char hex[3] = { code[0], code[1], 0 };
    
    	// Den Rückgabewert konvertieren wir explizit mit
    	// dem C++ static_cast. Dies soll nur die Sache
    	// verdeutlichen, also was hier eigentlich passiert.
    	return static_cast<char>(strtol(hex, NULL, 16));
    }
    
    // Übrigens wird in C und teilweise C++ NULL nur für einen
    // Nullzeiger verwendet. Man sollte also NULL nicht für 0
    // oder '\0' verwenden. In C++ gibt es zudem auch noch die
    // Möglichkeit ein nullptr Objekt zu bauen. Näher steht 
    // in der FAQ. Aber da ihr ja nicht richtiges C++ macht,
    // dürft ihr das sicher auch nicht verwenden. Kommt übrigens
    // in den nächsten Standard sogar als Schlüsselwort rein.
    

    5. Ich hoffe ich habe keine groben Fehler gemacht.
    6. Zwei Links, zu Einträgen in der FAQ, welche ich erwähnt habe:
    FAQ - C++ - NULL oder 0 (eher veraltet)
    FAQ - C++ - nullptr (neu)
    7. Erwarte nicht, dass sowas zum Standard bei der Hilfestellung wird. Sonst dürftest du von diesem Forum enttäuscht werden. Ich glaube, ich habe gerade ein wenig übertrieben 😃

    Grüssli



  • Daumen hoch für den Beitrag! Hoffentlich macht er was draus, erklären kannst du jedenfalls sehr gut 👍


  • Administrator

    Noch eine kurze Bemerkung. Habe meinen Code noch korrigiert. Mir ist aufgefallen, dass ich vergessen habe, dass strlen die Länge des C-Strings ohne die Null-Terminierung zurückgibt. Wenn also nichts ersetzt hätte werden müssen, wäre es zu einem Überlauf mit undefiniertem Verhalten gekommen, da die Null-Terminierung des Puffers in Speicher geschrieben worden wäre, welcher nicht reserviert wurde. Deshalb hat es nun ein +1 drin und deshalb wurde mein Post editiert.

    @Badestrand,
    Ehm, danke.
    *froh ist dem Galgen entkommen zu sein* 😃

    Grüssli



  • Du bist super!

    Nun hast du den Code zwar für mich geschrieben, aber ich denke mit deinen sehr ausführlichen Kommentaren kann ich mich hervorragend durch das Programm denken und jeden einzelnen Schritt nachverfolgen, was ich jetzt auch mal tun werde. Danach geb ich nochmal Feedback ab 🙂 Vorab auf jeden Fall erstmal vielen Dank für deine wirklich großartige Hilfsbereitschaft und mit meinem Lehrer werde ich mal einige Worte wechseln. So oder so möchte ich mich deiner Tipps annehmen und mich selbst schlau machen über richtiges C++, und auch werde ich meinen Lehrer bitten dies zu akzeptieren. 🙂

    Mit meinem Feedback kannst du entweder morgen schon oder spätestens Samstag rechnen! Noch 3x Danke für deine Bemühungen!

    Mit freundlichen Grüßen,
    Kevin



  • So, wie versprochen hier mein Feedback.

    Ich habe mir das Programm jetzt lange und oft angeschaut und mir quasi ein "Struktogramm" dazu gemacht. Durch Hilfe dessen und deine Erklärungen bin ich jetzt mit dem Quellcode vertraut, bzw. mit dem was er macht. Mir gefällt deine Strukturierung sehr gut und dein Code ist auf Grund der sinnvollen Kommentare und Einrückungen leicht nachvollziehbar. Allerdings habe ich noch 2-3 Fragen an dich.

    1. Warum benutzt du bei Kontrollstrukturen/Abfragen diese Variante: '\0' != *text und nicht *text != '\0' ? Hat das einen bestimmten Grund, bringt es einen Vorteil oder ändert es irgendetwas an der Geschwindigkeit?

    2. Wo läge der Unterschied, wenn ich statt ++text; einfach text++; benutzen würde?

    3. Ist die + 1 in dieser Deklaration: char* buffer = new char[strlen(text) + 1]; für den Nullterminator gedacht?

    4. Angenommen, ich lasse void changeText(char* dest, char const* text) rekursiv laufen. Welche Auswirkungen hätte das auf die Geschwindigkeit?

    Danke und mit freundl. Grüßen
    Kevin


Anmelden zum Antworten