Bestimmte Zeichenkette aus char* löschen



  • Shade Of Mine schrieb:

    sogar mit kompletter fehlerüberprüfung

    dir ist schon klar, dass 'assert' nur in der debug-version wirksam ist?



  • Undertaker schrieb:

    Shade Of Mine schrieb:

    sogar mit kompletter fehlerüberprüfung

    dir ist schon klar, dass 'assert' nur in der debug-version wirksam ist?

    das ist sinn der sache. logik fehler in der debug version abfangen.

    was anderes als sofort die anwendung beenden kann man eh nicht machen wenn ein logikfehler aufgetreten ist.



  • Shade Of Mine schrieb:

    perfektes beispiel wie man es nicht macht. dein Delete schreit foermlich
    danach speicher zu leaken.

    Wo sollte denn da was leaken.
    Man braucht nur dafür zu sorgen, das der reservierte Speicherplatz für
    jede Zeichenkette die zurückgegeben wird, mit free frei gegeben wird.

    Shade Of Mine schrieb:

    und strncpy terminiert nicht mit 0 wenn n<=strlen(src) ist.

    Das muss hier auch nicht, weil der Speicherplatz für die neue
    Zeichenkette mit calloc reserviert wird. Dadurch hat man die
    Terminierung im Falle n<=strlen(src) quasi 'frei Haus'.

    Shade Of Mine schrieb:

    was genau soll der sinn von pruefe_zeichenkette sein?

    Tja, wenn du den Kommentar über der Funktion gelesen hättest dann
    wüßtest du es.
    Aber möglicher weise hast du ihn gelesen und den Sinn nicht verstanden.

    Shade Of Mine schrieb:

    die fehler abfragen in Delete sind auch ein horror. wozu erst nen
    unsigned verlangen wenn du dann erstrecht wieder auf int wechselst, etc?

    Ganz einfach:
    Unigned, weil start_position und Anzahl logischer weise nicht negativ
    sein sollten.
    if ( (int) Anzahl < 0 )
    soll verhindern das der Benutzer einen negativen Wert benutzt und weil
    die Variable Anzahl vom Typ unsigned int ist, würde
    if ( Anzahl < 0 )
    bei einem negativen Wert nicht zu dem gewünschten Ergebnis führen, etc.

    Shade Of Mine schrieb:

    Lektion Nummer 1 beim Interface Design in C: NEVER EVER intern
    allokierten speicher nach aussen geben.

    Learning Interface Design by Shade Of Mine ?
    Der Sinn dieser Funktion ist doch gerade der, Zeichenketten zu erzeugen
    und nach aussen zu geben.
    Betrachte es als stand-alone-interface, für die Freigabe des Speicherplatzes ist der Benutzer verantwortlich.

    Shade Of Mine schrieb:

    // ... ( Auf die Darstellung des Quellcodes wird hier aus didaktischen Gründen verzichtet. )
    sogar mit kompletter fehlerüberprüfung

    Das glaubst du doch selbst nicht. Nicht einmal annähernd in der
    Debug-Version.

    Die Funktion soll aber gerade im Einsatz, also als Release-Version möglichst viele Fehlerquellen selbständig abfangen. Da werden dir deine asserts nichts nützen.

    Hier habe ich manch einen Fehler über stderr ausgegeben.
    In der Praxis schreibe ich die Fehlerursachen in einen char-Puffer, dann
    kann der Anwender entscheiden, ob und wie er die Fehlermeldung anzeigen
    möchte. ( Konsole, MessageBox, etc. )
    Und wie sein Programm darauf reagieren soll.

    Shade Of Mine schrieb:

    lahm ist das ding auch noch.

    Warum ? Welches Ding ?
    Sollte sich die Funktion in der Praxis als zu langsam herausstellen, kann man über Optimierungen immer noch nachdenken. Hier steht aber die Programm-Stabilität im Vordergrund.

    Shade Of Mine schrieb:

    sorry, aber das ist eine sehr miese lösung. ich kann ihr nix gutes abgewinnen.

    Diese Meinung kannst du ruhig beibehalten.
    Ich bin jemand, der gern dazulernt. Ich habe den Qeullcode so freizügig gepostet, damit er von den C-Profis ordentlich zerpflückt wird( insofern sie Zeit und Lust dazu haben ) und ich
    dadurch dazu lernen kann.
    Sorry, aber von deinen Argumenten konnte mich nicht ein einziges des Besseren belehren.

    MfG D.n.n.N. ( Der noch nettere Nachbar )



  • Shade Of Mine schrieb:

    Undertaker schrieb:

    Shade Of Mine schrieb:

    sogar mit kompletter fehlerüberprüfung

    dir ist schon klar, dass 'assert' nur in der debug-version wirksam ist?

    das ist sinn der sache. logik fehler in der debug version abfangen.
    was anderes als sofort die anwendung beenden kann man eh nicht machen wenn ein logikfehler aufgetreten ist.

    ihr geht beide von anderen voraussetzungen aus.
    das programm von "Der noch nettere Nachbar" versucht unerwarteten, chaotischen input abzufangen, während du davon ausgehst, dass der code nur intern verwendet wird und mistige eingaben ausschliesslich auf programmierfehler zurückzuführen sind.
    also wird das wohl ein thread, in dem alle aneinander vorbeireden. 😉



  • hallo zusammen

    also erstmal danke dass ihr hier alle so fleißig ward.

    hab mir jetzt alles mal durchgelesen, aber jeder hatte an dem code jemand anderen etwas, was nicht so ok war.

    was soll ich denn jetzt nehmen?

    gibt es eine "endversion" *gg*



  • MSS-Software schrieb:

    ...aber jeder hatte an dem code jemand anderen etwas, was nicht so ok war.
    was soll ich denn jetzt nehmen?
    gibt es eine "endversion" *gg*

    Die Entscheidung bleibt letztlich bei dir. Wenn du dich darauf verlassen kannst, das stets gültige Parameter übergeben werden, wäre meine Version mindestens zu 85% redundant und man könnte die ganze Fehlerprüfung auch gleich weglassen.
    Möchtest, bzw. musst du keine 'Read-Only-Strings' benutzen, kannst du auch die dynamische Reservierung von Arbeitsspeicher komplett weglassen und die Zeichenketten einfach in ihrem Puffer schrumpfen lassen. usw, usw, usw.
    Kurzum: Es hängt vom Anwendungsfall ab.

    Ich habe jedenfalls noch etwas verbesserungswürdiges entdeckt.
    Es macht durchaus Sinn
    #define ZK_MAXLEN UINT_MAX
    durch
    #define ZK_MAXLEN INT_MAX
    zu ersetzen, denn (int) neue_laenge <= 0
    liefert für neue_laenge = INT_MAX + 1 einen wahren Wert.

    Naja, INT_MAX sollte ja wohl auch ausreichen.
    Wer geübt im Tippen ist und 255 Anschläge pro Minute schafft, der ist mit dem Eintippen einer solchen Zeichenkette schon nach ca. 16 Jahren fertig. 😃 ( 4 Byte Integer vorausgesetzt )

    MfG



  • also ihr könnt mir ja sagen was ihr wollt, aber ich kriege es immer noch net hin

    ich hab jetzt mal folgendes gemacht:

    char* Delete(char* Zeichenkette, int start_position, int Anzahl)
    {
    	char *rueckgabe_wert = (char*)malloc(strlen(Zeichenkette+1));
    	rueckgabe_wert = Zeichenkette;
    	for ( int i = 1; i < Anzahl; i++ )
    		rueckgabe_wert[start_position] = 'x';
    	return rueckgabe_wert;
    }
    

    ich weiß, ihr werdet mir jetzt alle ins gesicht springen weil ich den speicher noch nicht wieder freigebe 😞

    also: bei dem code hängt er sich auf, sobald er das zeichen x zuweisen will

    lasse ich die zeile

    rueckgabe_wert = Zeichenkette;
    

    aber weg, schreibt er mir da problemlos rein.

    wo isn da der unterschied?

    ich möchte doch einfach nur ein zeichen durch ein anderes ersetzen?



  • MSS-Software schrieb:

    ich weiß, ihr werdet mir jetzt alle ins gesicht springen weil ich den speicher noch nicht wieder freigebe 😞

    Nein, deswegen springt dir niemand ins Gesicht, aber: (a) brauchsst du den Rückgabewert von malloc nicht zu casten und (b) vergisst du mit der Zeile 'rueckgabewert=Zeichenkette' die Adresse des neureservierten Speicherbereichs und biegst deinen Zeiger um auf den übergebenen Parameter (das bedeutet, in der Schleife schreibst du nicht in dem Speicherbereich, den malloc() dir besorgt hat, sondern in dem, den du von außen bekommen hast).

    Wenn du den Inhalt von 'Zeichenkette' kopieren willst, brauchst du strcpy().



  • wenn ich den aber nicht caste, kommt er mir damit

    'Initialisierung': 'void *' kann nicht in 'char *' konvertiert werden
    

    gut, strcpy hat geholfen 😉

    ich wollte mich dann nochmal bei euch entschuldigen.

    hab bis jetzt hauptsächlich immer nur mit strings gearbeitet in der MFC

    gibts denn irgendein tut oder so, was ich mir zu diesem thema mal durchlesen könnte?



  • MSS-Software schrieb:

    wenn ich den aber nicht caste, kommt er mir damit

    'Initialisierung': 'void *' kann nicht in 'char *' konvertiert werden
    

    Wenn du C Programme schreibst, solltest du auch einen C-Compiler verwenden, um sie übersetzen zu lassen 😉 (ein C++ Compiler ist an dieser Stelle etwas pingeliger mit der Typumwandlung)


Anmelden zum Antworten