String zerteilen



  • Hi,

    ich möchte gerne einen String zerteilen.
    Zum Beispiel einen String wie diesen: "D:\Spiele\Quake III Arena\quake3.exe".
    Das Problem dabei ist, das der String immer anders ist. Es könnte auch "C:\Anwendungen\Games\id software\quake 4\quake4.exe" sein.
    Alles was ich will, ist den Teil vor dem "x.exe" zu entfernen, und den namen der exe inklusive der Endung in eine Variable zu kopieren um eben diese auszugeben.

    Klar, ich kann einen String teilen, indem ich nach einem bestimmten Zeichen suche, zB nach einem "\". Damit wäre das Problem aber leider nicht gelöst, denn in einem Pfad zu einer exe sind ja meistens mehrere "\" vorhanden.

    Hat einer eine Idee wie man dies noch lösen könnte? Mir fällt grad nicht mehr viel ein.

    Gruß,
    Felix



  • Den String von rechts nach links zeichenweise in ein dynamisches Array einlesen, bis der erste Backslash kommt.
    Danach die Schleife abbrechen.

    Im Array steht nun der Dateiname, allerdings verkehrt(du musst ihn also entweder noch umdrehen oder aber imm von hinten das Array auslesen).

    Grüße,
    Harri



  • harry3 schrieb:

    Den String von rechts nach links zeichenweise in ein dynamisches Array einlesen, bis der erste Backslash kommt.
    Danach die Schleife abbrechen.
    Im Array steht nun der Dateiname, allerdings verkehrt(du musst ihn also entweder noch umdrehen oder aber imm von hinten das Array auslesen).

    sorry, aber das ist ja echt 'ne schnapsidee 😉
    so isses einfacher:

    #include <stdio.h>
    
    char *remove_path (char *path)
    {
       int l = strlen(path);
       while (l)
          if (path[l--] == '\\')
             return &path[l+2];
       return path;
    }
    
    int main()
    {
       printf ("%s\n", remove_path ("D:\\Spiele\\Quake III Arena\\quake3.exe"));
    }
    

    :xmas2:



  • um Strings zu zerteilen gibt es die ekelige Funktion man: strtok(3)

    Aber was du wohl eher brauchst ist man: strrchr. Damit suchst du eben das zuletzt vorkommende '\' im String.

    #include <string.h>
    #include <stdio.h>
    
    char const *remove_path(char const *str) {
      char const *ret=strrchr(str, '\\');
      return ret ? ret+1 : str;
    }
    
    int main() {
      printf("%s\n", remove_path("foo\\bin"));
    }
    

    edit: Fehler behoben



  • hehe, rüdi,
    mach mal bei dir 'remove_path ("foo.exe")'
    mein schnellschuss macht's wenigstens richtig 😉
    :xmas2:



  • s/NULL/str



  • finix schrieb:

    s/NULL/str

    wie meinen? 😕



  • ten schrieb:

    finix schrieb:

    s/NULL/str

    wie meinen? 😕

    was er sagen will: Ersetz einfach NULL durch str in meinem Code und es läuft richtig...



  • Danke euch! 🙂

    rüdiger schrieb:

    um Strings zu zerteilen gibt es die ekelige Funktion man: strtok(3)

    Aber was du wohl eher brauchst ist man: strrchr. Damit suchst du eben das zuletzt vorkommende '\' im String.

    #include <string.h>
    #include <stdio.h>
    
    char const *remove_path(char const *str) {
      char const *ret=strrchr(str, '\\');
      return ret ? ret+1 : str;
    }
    
    int main() {
      printf("%s\n", remove_path("foo\\bin"));
    }
    

    edit: Fehler behoben

    Heißt es nicht immer "const char" anstatt "char const"? Oder ist es egal?

    Gruß,
    Felix :xmas1:

    //Edit:
    Also habs nun so gemacht wie rüdiger:

    const char *remove_path(const char *path)
    {
      const char *ret = strrchr(path, '\\');
      return ret ? ret + 1 : path; 
    }
    

    THX und liebe Grüße,
    Felix



  • felix schrieb:

    Heißt es nicht immer "const char" anstatt "char const"? Oder ist es egal?

    Ist egal.

    http://c-faq.com/ansi/constptrconst.html



  • #include <stdio.h>
    
    char *remove_path (char *path)
    {
       int l = strlen(path);
       while (l)
          if (path[l--] == '\\')
             return &path[l+2];
       return path;
    }
    
    int main()
    {
       printf ("%s\n", remove_path ("D:\\Spiele\\Quake III Arena\\quake3.exe"));
    }
    

    Zu dem Code(gepostet von 'ten') hab ich noch eine Frage:
    Ich übergebe an die Funktion remove_path ja einen String, der soweit ich weiß auf dem Stack liegt(?).
    Nun gibt die Funktion remove_path ja eine Adresse zurück, die auf den neuen Anfangspunkt des Strings zeigt. Doch ist es garantiert, dass der dort liegende String überhaupt noch gültig ist? Schließlich ist die Funktion remove_path bereits beendet, wenn printf den String ausgeben will.

    Grüße,
    Harri



  • hi,
    so'ne stringkonstante kommt nicht auf den stack. die steckt im 'speicher für konstanten' (wie auch immer das platformspezifisch gelöst ist), und ist die ganze zeit über vorhanden. temporär sind nur diese adressen, mit denen die funktion arbeitet z.b. bei übergabe die anfangsadresse der stringkonstanten, bei der rückgabe eine adresse die mitten rein zeigt...
    :xmas2:



  • Und selbst wenn du dort etwas übergibst, was auf dem Stack liegt, dann gehört es zu dem Stack-Bereich der aufrufenden Funktion. Das heißt, selbst mit dieser Konstruktion

    char* remove_path(char* path){...}
    
    int main()
    {
      char path[MAX_PATH];
      scanf("%s",path);
    
      printf("Dateiname: %s\n",remove_path(path));
    }
    

    gibt es keine Probleme, weil das Array der main()-Funktion gehört und erst an deren Ende wieder zerlegt wird.

    (das Problem mit dem Stack bekommst du nur, wenn du lokal (in der Funktion) ein Array anlegst und dessen Adresse zurückgibst)



  • hi,
    am besten finde ich diese variante:

    char *remove_path (char *path)
    {
        char *p;
        for (p = path; *path; path++)
            if (*path == '\\')
                p = path+1;
        return p;
    }
    

    braucht weder 'strlen' noch sonstwas...
    :xmas2:



  • Ja, super.

    Rüdigers Variante hat den gigantischen Nachteil eine Standardfunktion zu nutzen, ist dafür aber auch kürzer & lesbarer.



  • finix schrieb:

    Ja, super.
    Rüdigers Variante hat den gigantischen Nachteil eine Standardfunktion zu nutzen, ist dafür aber auch kürzer & lesbarer.

    hauptsache, du hast was zu meckern, ne? 🙄



  • ten schrieb:

    finix schrieb:

    Ja, super.
    Rüdigers Variante hat den gigantischen Nachteil eine Standardfunktion zu nutzen, ist dafür aber auch kürzer & lesbarer.

    hauptsache, du hast was zu meckern, ne? 🙄

    Tut mir nicht Leid dass du dich mal wieder unnötigerweise von meiner Meinung angegriffen fühlst. Und deine Vermutung ist komplett haltlos, ansonsten dürfte es dir nämlich nicht schwer fallen aufzuzeigen inwiefern ich an rüdigers Implementation "rumgemeckere".



  • finix schrieb:

    ...dass du dich mal wieder unnötigerweise von meiner Meinung angegriffen fühlst.

    tu' ich das?

    finix schrieb:

    ...ansonsten dürfte es dir nämlich nicht schwer fallen aufzuzeigen inwiefern ich an rüdigers Implementation "rumgemeckere".

    du meckerst nicht über rüdis code, nee, das hab' ich nicht gemeint...
    :xmas2:



  • @ten: Was meinst du, warum irgendjemand sich hingesetzt und die Standardfunktionen zusammengetragen hat? Bestimmt nicht, damit jeder Programmierer sich hinsetzen muß und sie nochmal von Hand nachprogrammieren muß.



  • CStoll schrieb:

    @ten: Was meinst du, warum irgendjemand sich hingesetzt und die Standardfunktionen zusammengetragen hat? Bestimmt nicht, damit jeder Programmierer sich hinsetzen muß und sie nochmal von Hand nachprogrammieren muß.

    na, hast ja recht. die haben schon ihre daseinsberechtigung. ich find's aber trotzdem am schönsten, wenn man ohne auskommt...
    :xmas2:


Anmelden zum Antworten