String in C kürzen



  • Hallo Leute,

    ich habe folgendes Problem. Ich lese aus einer Datei einen Speicherpfad ein und speichere diesen in einer Variablen. Nun muss ich die Endung dieses Strings abschneiden und einen anderen anfügen. Leider habe ich das, auch mit Hilfe der Suchfunktion und einigen Diskussionen nicht hinbekommen.
    In der Variablen steht momentan:
    c:\Ordner\test.ght
    Ich möchte erhalten:
    c:\Ordner\test.bnr

    Der Ordner kann immer ein anderer sein. Wie gehe ich vor? Ich verwende einfachstes C.

    Vielen Dank schon mal!

    Chris



  • null terminierung verschieben und dann ein strcat



  • const char *ersetzeDateiEndung(char *dateiname,const char *endung)
    {
      char *p;
      if( !dateiname )
        return 0;
      if( !(p=strrchr(dateiname,'.')) )
        return 0;
      return strcpy(p,endung);
    }
    

    Den Aufruf bekommst du wohl selbst hin?



  • Wutz schrieb:

    const char *ersetzeDateiEndung(char *dateiname,const char *endung)
    {
      char *p;
      if( !dateiname )
        return 0;
      if( !(p=strrchr(dateiname,'.')) )
        return 0;
      return strcpy(p,endung);
    }
    

    Den Aufruf bekommst du wohl selbst hin?

    bullet proof ist aber was anderes;)



  • "bullet proof" war nicht das thema ...



  • Frank Erdorf schrieb:

    "bullet proof" war nicht das thema ...

    was das für ein scheiß 😕



  • Bedenke aber, strcat ist langsam wenn du den Anfang abschneiden mußt.

    Um den Anfang abzuschneiden verwendest du dafür am besten die Pointerarithmetik.

    Bsp:

    char c[] = "Das ist mein Text. Wir wollen nur diesen Satz.";
    char *p = &c;
    
    c = &p - 18;
    


  • @-_-

    Hier geht es darum,
    daß die von Wutz aufgeführte Funktion theoretisch nicht sicher ist.
    In der Praxis ist diese Funktion normalerweise schon sicher,
    weil sie die meisten checks schon macht.

    Wie auch immer,
    je nach Nutzdaten kann es hier zu einem Stackoverflow oder Heapoverflow kommen.
    Das kann zu undefiniertem Verhalten und zum Absturz des Programms führen.
    Schlimmer noch es kann ausgenutzt werden um Angriffe zu starten und Fremdcode auszuführen.

    Insbesondere ein Stackoverflow lässt sich vergleichsweise einfach für Angriffe
    ausnutzen, weil die Rücksprungadressen auf dem Stack liegen.
    Man braucht 'nur' diese Adressen geschickt zu überschreiben und
    kann Fremdcode in den Daten ausführen.

    Wie schon gesagt,
    genau das ist hier nicht Thema.

    noch etwas:
    wenn du was nicht verstehst, kannst du auch gerne freundlicher fragen.

    Gruß Frank



  • Den Schluß kannst du aber auch ganz einfach abschneiden, und zwar so:

    char c[] = "Das ist mein Text. Wir wollen nur diesen Satz.";
    
    c[18] = '\0';  /* Das schneidet dir einfach den letzten Satz ab und ist viel schneller als strcat */
    

    Deswegen ist Pointerarithmetik ja auch so toll.
    Es ist einfach sau schnell.



  • Frank Erdorf schrieb:

    @-_-

    Hier geht es darum,
    daß die von Wutz aufgeführte Funktion theoretisch nicht sicher ist.
    In der Praxis ist diese Funktion normalerweise schon sicher,
    weil sie die meisten checks schon macht.

    Wie auch immer,
    je nach Nutzdaten kann es hier zu einem Stackoverflow oder Heapoverflow kommen.
    Das kann zu undefiniertem Verhalten und zum Absturz des Programms führen.
    Schlimmer noch es kann ausgenutzt werden um Angriffe zu starten und Fremdcode auszuführen.

    Insbesondere ein Stackoverflow lässt sich vergleichsweise einfach für Angriffe
    ausnutzen, weil die Rücksprungadressen auf dem Stack liegen.
    Man braucht 'nur' diese Adressen geschickt zu überschreiben und
    kann Fremdcode in den Daten ausführen.

    Wie schon gesagt,
    genau das ist hier nicht Thema.

    noch etwas:
    wenn du was nicht verstehst, kannst du auch gerne freundlicher fragen.

    Gruß Frank

    wo steht das eine datei eine endung hat... nirgends daher sollte man erstmal die datei+endung aus dem gesamten sting rauslösen und dann die endung entfernen. da dies das thema dieses threads ist habe ich das geschrieben... da ging es noch nicht mal buffer overflows o.ä.

    noch etwas:
    wenn ichs dir genauer erklären soll sag bescheid 😋



  • hum0r -> nein schrieb:

    da ging es noch nicht mal um buffer overflows o.ä.



  • @noobKing?
    Sorry,
    dann habe ich das kurze Posting wohl missinterpretiert,
    war aber nicht wirklich schwer.

    wo steht das eine datei eine endung hat... nirgends

    korrekt,
    wenn die Datei keine Endung hat,
    dann macht die Funktion von Wutz nichts und signalisiert das auch:

    if( !(p=strrchr(dateiname,'.')) )
        return 0;
    

    Gruß Frank



  • ich bin eher der quertreiber 😉 aber laß doch mal die function von wutz auf folgenden string los

    /hello.world/file
    


  • Jetzt wird es aber deutlich schwieriger als in der Aufgabenstellung ...

    na dann schreib du doch mal was,
    du hast dir ja auch diesen Testcase ausgedacht 😉
    und wenn dann schon bitte auch winlike \ berücksichtigen .. 😉

    Gruß Frank



  • Da schaut man mal ein paar Stunden nicht nach und schon tummeln sich die Querulanten, aber wenigstens einer bemüht sich um Pragmatismus.

    Der Fragesteller hat sich noch nicht geäußert, vielleicht genügt ihm der Vorschlag ja, zumal er einfachstes C bevorzugt.
    Die Vorschlagsfunktion erhebt keinen Anspruch auf Robustheit sämtlichen Randbedingungen gegenüber, das schreibe ich nicht jedes Mal explizit dazu, sie genügt genau dem genannten Anwendungsfall.



  • char *replace(char *path,char *ext){
    	char *ret = strrchr(path,'/');
    	if(!ret)
    		ret = path;
    	ret = strrchr(ret,'.');
    	if(ret){
    		if(strlen(ret) >= strlen(ext))
    			strcpy(ret,ext);
    		else
    			return 0;
    	}
    	return path;
    }
    


  • wutz schrieb:

    zumal er einfachstes C bevorzugt

    bei solchen sätzen bekomm ich nen kropf einfachstes c heißt nicht das es falsch sein darf ⚠



  • Frank Erdorf schrieb:

    Wie auch immer,
    je nach Nutzdaten kann es hier zu einem Stackoverflow oder Heapoverflow kommen.
    Das kann zu undefiniertem Verhalten und zum Absturz des Programms führen.
    Schlimmer noch es kann ausgenutzt werden um Angriffe zu starten und Fremdcode auszuführen.

    Insbesondere ein Stackoverflow lässt sich vergleichsweise einfach für Angriffe
    ausnutzen, weil die Rücksprungadressen auf dem Stack liegen.
    Man braucht 'nur' diese Adressen geschickt zu überschreiben und
    kann Fremdcode in den Daten ausführen.

    Warum kann es da zu einem Stackoverflow kommen? Den Heapoverflow hab ich verstanden, aber beim anderen hapert es noch.

    -_o schrieb:

    strcpy(ret + 1,ext);
    

    sonst wird der Punkt mit überschrieben.



  • Antoras schrieb:

    strcpy(ret + 1,ext);
    

    sonst wird der Punkt mit überschrieben.

    merci 👍



  • dann muß man doch sicher auch noch das strlen() anpassen 😕


Log in to reply