1. Dashboard
  2. Forum
    1. Unerledigte Themen
  3. Mitglieder
    1. Letzte Aktivitäten
    2. Benutzer online
    3. Team-Mitglieder
    4. Trophäen
    5. Mitgliedersuche
  4. Tutorial Bereich
  • Anmelden
  • Registrieren
  • Suche
Dieses Thema
  • Alles
  • Dieses Thema
  • Dieses Forum
  • Seiten
  • Forum
  • Lexikon
  • Erweiterte Suche
  1. Informatik Forum
  2. Webmaster & Internet
  3. Entwicklung

Help bei Funktionen und Stringteile ersetzen

    • Frage
  • Heavy
  • 16. November 2003 um 14:31
  • Unerledigt
  • Heavy
    18
    Heavy
    Mitglied
    Reaktionen
    2
    Punkte
    3.507
    Beiträge
    664
    • 16. November 2003 um 14:31
    • #1

    http://www.pri.univie.ac.at/~itep/ws0304/hue/hue05a.html

    Tjo ich hab schon Schwierigkeiten beim lösen eines dieser Beispiele (Hauptuni- EPROG)...
    Hoffentlich kennt sich jemand auch mit C+ aus.

    Ich hab mich auf Bsp8 konzentriert.
    Das Bsp8 hört sich zwar einfach an aber damit hab ich auch schon Probleme. :frowning_face:
    Ich bitte um eure Hilfe!

    Code
    <include>iostream.h
     
    char replace(char par1, char par2)
    {
    ..
    ...
    ...
    }
     
    int main(){
    char a[100];
    char b[100];
    char kette[100];
     
    for (int i=0; i<=100; i++)
    cin>>kette[i];
    replace()
    ...
    ...
    }
    Alles anzeigen



    Sorry ich weiss wirklich nicht mehr was zu tun ist...bin die ganze Nacht gesessen ohne Erfolg.

    Religion ist ein Glaube,
    Wissenschaft als Teilgebiet ist ein Glaube,
    die Wahrheit liegt in der Gegenwart des Menschen.

  • Kongo
    6
    Kongo
    Mitglied
    Punkte
    295
    Beiträge
    44
    • 17. November 2003 um 14:57
    • #2

    Tja mein erster Versuch sieht so aus:

    Das Problem is nur, das der globale String groß genug sein muss, um das Ergebnis
    zu speichern, da kein Boundary-Checking gemacht wird.

    C
    #include <stdio.h>
    #include <iostream.h>
    
    
    char globalerstring[100] = "Das ist ein Teststring";
    
    
    void replace(const char* szOld, char* szNew)
    {
       char* szTemp = globalerstring;
       char* szCopy = 0;
       int iLen = 0, i = 0;
    
    
       // Läne von globalen String erfassen
       while (*szTemp++);
       iLen = (szTemp - globalerstring - 1);
    
    
       // Kopie machen
       szTemp = globalerstring;
       szCopy = new char[iLen+1];
       do {
          szCopy[i] = *szTemp;
          i++;
       } while(*szTemp++);
    
    
       // Neuen String erstellen
       int j=0, k=0;
       for (int i=0; i < iLen; i++) {
          j=0;
          do {
             if (szOld[j] == 0) {
                i += j;
                // Wort gefunden also ersetzen
                char* atnew = szNew;
                j=0;
                do {
                   globalerstring[k++] = *atnew; 
                } while(*++atnew);
             }
             if (szCopy[i+j] != szOld[j])
                break;
             j++;
          } while(true);
    
    
          globalerstring[k++] = szCopy[i];
       }
    }
    
    
    void main()
    {
       cout << globalerstring << "\n";
       replace("ein","absolut kein");
       cout << globalerstring << "\n";
    }
    Alles anzeigen

    :thumb: Geschrieben nach der alten, neuen und zukünftigen Rechtschreibung! :thumb:

  • davie
    2
    davie
    Mitglied
    Punkte
    15
    Beiträge
    3
    • 18. November 2003 um 23:25
    • #3

    Also...
    Zuerst einmal heftige Kritik an den Leuten, die euch das beigebracht haben, jetzt nach 5 Jahren C++ unter ISO Standardregeln..
    Der Header iostream.h sowie stdio.h sind veraltet. Tja, nix zu machen. Im "neuen" (5 Jahre alten) C++ Standard gibt es dafür die Header iostream und cstdio.

    C
    #include <iostream>
    #include <cstdio>
    using namespace std;


    Die Namen sind in den neuen Headern aber alle im Namensraum std untergebracht, also muss man sie mit einer using direktive sichtbar machen (oder mit using deklarationen, wie auch immer man es bevorzugt - oder immer explizit)

    Dann:
    zu "void main": Main muss immer "int" zurückgeben. Ebenfalls im Standard, sowohl im C als auch im C++ Standard. Es gab nie eine "void" Version in C++.
    Ein standardkonformer Compiler (zum Beispiel g++) würde den Code gar nicht erst kompilieren.

    Zum Thema globale Variablen: Ich hoffe ihr wisst, dass es eine Unart ist, sie zu benutzen.
    Wenn's nun aber vorgegeben ist, so wie hier, dann kann man nix machen.

    Ich hoffe außerdem, dass ihr die string Klasse von C++ kennt.

    IMHO eine total dumme Aufgabe: Ihr werdet immer Librarys benutzen dürfen, vor allem die vom Standard definierten. Wozu etwas programmieren, dass es schon längst gibt?!

    Zurück zum Code von Kongo.
    So eine riesige Funktion solltest du in mehrere kleine aufsplitten. Ein solches Trumm ist schwer wartbar und schlecht erweiterbar.
    Die ungarische Notation ist in C++ obsolet. Niemand sollte sie mehr verwenden.
    Aussagekräftige Namen sind 100mal besser als jedes Präfix.
    IMHO machen sie den Code nur noch schwerer lesbar.
    Außerdem verwendest du new. Ich sehe aber keine delete (bzw. delete[]). Da entstehen schnell riesige Speicherlöcher.

    Bleiben wir gleich beim Thema "erweiterbar".
    Schonmal versucht, mit deiner Version ein

    Code
    replace("ein","absolut kein");
    replace("absolut kein","ein");


    durchzuführen?
    Speicherzugriffsfehler - ist die Ausgabe auf meiner Konsole
    Da stimmt etwas nicht.

    Naja, hier ein Vorschlag von mir, um diese Aufgabe zu lösen:

    C
    #include <iostream>
    #include <cassert>
    using namespace std;
    
    
    char global_ist_kaese[100] = "Das ist ein Teststring und eine Banane";
    
    namespace my { //namen immer schön kapseln
    
    
          //ein paar grundlegende sachen
         //ptrdiff_t ist das ergebnis einer subtraktion von zwei zeigern
    	std::ptrdiff_t strlen (const char *str) {
    		const char *ptr = str;
    		while (*ptr++); return ptr-str;
    	} 
    
    
        //gibt true zurück, falls der anfang von str dasselbe ist wie what.
    	bool begin_eq (const char *str, const char *what) {
                    assert(strlen(str) > strlen(what)); //kommt in der release version natürlich raus
    		while (*what) {
    			if (*str++ != *what++) return false;
    		}
    		return true;
    	}
    
        //kopiert ohne abschließende null von from nach to
    	void copy (char *to, const char *from) {
    		while (*from) *to++ = *from++;
    	}
    
       //ersetzt alle what in str mit with.
    	void strrepl (char *str, const char *what, const char *with) {
                  //temporärer string mit inhalt des globalen
    		char *del, *tmp = del = new char[strlen(str)];
    		copy(tmp,str);
    	     //zum aufspeeden	
    		size_t lwith = strlen(with)-1;
    		size_t lwhat = strlen(what)-1;
    
    		while (*str++ = *tmp++) {
    			if (begin_eq(tmp,what)) {
    				copy(str,with);
    				tmp+=lwhat;
    				str+=lwith;
    			}
    		}
    		//niemals vergessen!
    		delete [] del;
    	}
    
    
    }
    //und jetzt: wir wollen die aufgabenstellung nicht vernachlässigen
    void die_besagte_funktion () {
    	my::strrepl(global_ist_kaese, "ein", "absolut kein");
    }
    
    
    int main() {
    
       cout << global_ist_kaese << endl;
       my::strrepl(global_ist_kaese,"ein","absolut kein");
       cout << global_ist_kaese << endl;
       my::strrepl(global_ist_kaese,"absolut kein","ein");
       cout << global_ist_kaese << endl;	
    
    
    //achja: return 0 wird von standardkonformen Compilern am Ende immer automatisch eingefügt.
    }
    Alles anzeigen


    Da lässt sich allerdings sicher noch was rausholen, performancetechnisch.
    Naja, nur mal ein Denkanstoß und Mahnzeichen.

    Für Fragen:
    http://www.c-plusplus.de/forum
    Im C++ Subforum bekommt ihr eure Antworten

    cya

  • beefy
    13
    beefy
    Mitglied
    Reaktionen
    18
    Punkte
    1.683
    Beiträge
    304
    • 19. November 2003 um 23:51
    • #4
    Zitat

    Die ungarische Notation ist in C++ obsolet. Niemand sollte sie mehr verwenden.

    Ich verstehe nichts von C++ und benutze auch nicht die ung. Notation, mich würde aber trotzdem interessieren warum diese in C++ obsolet sein sollen..?

  • davie
    2
    davie
    Mitglied
    Punkte
    15
    Beiträge
    3
    • 20. November 2003 um 01:07
    • #5
    Zitat von beefy

    Ich verstehe nichts von C++ und benutze auch nicht die ung. Notation, mich würde aber trotzdem interessieren warum diese in C++ obsolet sein sollen..?


    Sollte vielleicht besser heissen "durch C++ unnoetig geworden".
    Du hast nicht nur eine kleine Menge eingebauter Typen (char, int und zeiger darauf), sondern kannst dir eigene definieren - inklusive Vererbung und Polymorphie. Wie willst du das in der ungarischen Notation darstellen?
    IMHO ist ein aussagekraeftiger Name viele Male besser als jedes Praefix (das hab ich sicher oben auch schon gesagt)
    Objekte sollten ausserdem idR nur relativ kurz existieren. Da vergisst man den Typ schon nicht.
    Ausserdem hab ich mehr Tipparbeit.
    Verschlimmbessere mir die Lesbarkeit.
    In C++ ist es schlicht unnoetig irgendwelche Praefixe, egal ob in ungarischer Notation, fuer Klassen, oder fuer Elementvariablen einzufuehren.
    Es geht einfach nur um die (Un)notwendigkeit

  • Maximilian Rupp 27. Dezember 2024 um 12:08

    Hat das Thema aus dem Forum Programmieren nach Entwicklung verschoben.

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!

Benutzerkonto erstellen Anmelden

Rechtliches

Impressum

Datenschutzerklärung