Länge von String ausgeben ohne Bibiliothek einbinden



  • Hallo,

    ich hab mich daran versucht die Länge eines Strings zu rückzugeben ohne die üblichen bekannten Funktionen.
    Da ich noch Anfänger habe, habt Gnade mit mir.
    Hier ist mein Quellcode:
    #include <stdio.h>

    size_t strlen (const char* str){ //Gibt die Länge eines Strings zurück
    int i=1;
    do { (i++);} while (*str != '\0');

    return i;
    }

    int main (void){
    const char* str;
    int j;
    printf("Geben sie die Größe des Strings ein:\n");
    scanf("%d", &j);
    char str1 [j]
    str = &str1;
    printf("Die Länge des Strings ist %u \n",strlen(str));

    return 0;
    }

    Leider funktioniert es noch nicht und ich bin mittlerweile ziemlich aufgeschmissen. Ich möchte im Anschluss eine weitere Funktion implementieren, die die Anzahl der Vorkomnisse eines Zeichens in einem String zurück gibt.Aber soweit bin ich noch nicht 😕

    Vielleicht könnt ihr mir weiterhelfen!
    Danke 🙂



  • Was funktioniert denn nicht?

    Dein Code dürfte der Compiler schon nicht übersetzen.

    Was willst du zum Beispiel mit der Zeile erreichen:

    char str1 [j]
    

    abgesehen, dass ein Semikolon am Ende fehlt.

    Warum soll der User die Länge des Strings eingeben? Dann musst du doch nichts mehr zählen. Sinnvoller wäre es doch, wenn der User den String eingibt, dessen Länge du bestimmen möchtest.

    P.S. Nutze das nächste mal bitte Code Tags. Einfach den Code markieren und auf das "C" unter dem 😡 Smilie klicken.



  • Die Länge eines Strings hat nicht unbedingt etwas mit der Länge des Speicherbereichs zu tun, in dem er abgelegt ist.

    Du solltest Bezeichner (Funktions und Variablennamen) aus der Standardbibliothek nicht für eigene Bezeichner verwenden.
    Z.B my_strlen oder strlength oder str_len oder ...

    Damit du die Länge feststellen kannst, musst du jedes ZEichen im String überprüfen.
    Im Augenblick überprüfst du nur die allererste Stelle, da du str nicht veränderst.

    Der Rückgabetyp deiner Funktion ist size_t , die Variable, die das erledigt aber vom Typ int
    Ein Richtige Formatspecifier für den Typ size_t ist z.B "%zu"

    Es gibt auch Strings der Länge 0, den Leerstring "".

    Du kannst in C nicht die Größe eines Speicherbereichs anhand des Zeigers auf seine Anfangsdresse ermitteln.
    Die Größe musst du immer extra mitführen.



  • Schlangenmensch schrieb:

    Warum soll der User die Länge des Strings eingeben? Dann musst du doch nichts mehr zählen. Sinnvoller wäre es doch, wenn der User den String eingibt, dessen Länge du bestimmen möchtest.

    P.S. Nutze das nächste mal bitte Code Tags. Einfach den Code markieren und auf das "C" unter dem 😡 Smilie klicken.

    Das werde ich direkt ändern, ist echt sinnvoller den String einzugeben und dann davon die Länge zu bestimmen.

    Mit den Code Tags habe ich übersehen, werde ich demnächst aber benutzen! 🙂



  • DirkB schrieb:

    Damit du die Länge feststellen kannst, musst du jedes ZEichen im String überprüfen.
    Im Augenblick überprüfst du nur die allererste Stelle, da du str nicht veränderst.

    Der Rückgabetyp deiner Funktion ist size_t , die Variable, die das erledigt aber vom Typ int
    Ein Richtige Formatspecifier für den Typ size_t ist z.B "%zu"

    Es gibt auch Strings der Länge 0, den Leerstring "".

    Du kannst in C nicht die Größe eines Speicherbereichs anhand des Zeigers auf seine Anfangsdresse ermitteln.
    Die Größe musst du immer extra mitführen.

    Okay, das mit size_t hab ich dirket geändert, danke!

    Mmh. Ich hab eine Aufgabe hier vorliegen und die gibt halt vor, dass ich da mit dem Zeiger arbeiten soll. Geht das wirklich nicht?
    Daher hab ich auch die Bezeichnungen übernommen.

    Str. versuche ich jetzt mal abzuändern. Leider fehlt mir noch die Idee dazu, aber ich überlege mal weiter!

    Danke euch beiden schonmal 🙂



  • tenana schrieb:

    Mmh. Ich hab eine Aufgabe hier vorliegen und die gibt halt vor, dass ich da mit dem Zeiger arbeiten soll. Geht das wirklich nicht?

    Hab ich das irgendwo geschrieben?

    In Arrayschreibweise würdest du

    while (str != '\0');
    

    *schreiben.
    Du liest also in jedem Schleifendurchlauf ein anderes Element.

    Das geht auch in Zeigerschreibweise.
    Da du die Anfangsadresse von deinem String nicht mehr brauchst, kannst du auch [i]str* selber verändern.
    str, nicht *str. Großer Unterschied.

    Dein Schleifentyp ist auch etwas unglücklich gewählt.

    Aber bevor wir hier rumraten, was du wie geändert hast, zeig lieber den aktuellen Code.



  • tenana schrieb:

    ist echt sinnvoller den String einzugeben und dann davon die Länge zu bestimmen.

    Es muss aber vorher genug Platz für den String sein.

    Im übrigen kannst du deine Funktion schneller testen, wenn du sie mehrmals mit festen Strings aufrufst.
    Und wenn du einen eigenen Funktionnamen nimmst, kannst du sogar die Ergebnisse vergleichen.

    void teste_mein_strlen{char *str)
    { printf("my_strlen: %5zu  strlen: %5 <%s>\n", my_strlen(str), strlen(str), str); 
    }
    
    teste_mein_strlen("");           // 0
     teste_mein_strlen("1");          // 1
     teste_mein_strlen("12345");
     teste_mein_strlen("1234567890");
    


  • wenn du auf das i-te element des speicherbereichs, auf das der zeiger zeigt, zugreifen möchtest, machst du das mit

    *(meinzeiger + i)
    

    meinzeiger ist dabei die anfangsadresse, i ist die anzahl der bytes, um die der zeiger erhöht werden soll und mit dem derefenzierungsoperator greifst du eben auf den wert an der speicherstelle zu.



  • Wade1234 schrieb:

    wenn du auf das i-te element des speicherbereichs, auf das der zeiger zeigt, zugreifen möchtest, machst du das mit

    *(meinzeiger + i)
    

    Da ist kein Unterschied zu meinzeiger[i]. Keiner.

    Denn der Compiler wandelt das ganz von alleine um.

    Wade1234 schrieb:

    meinzeiger ist dabei die anfangsadresse,

    richtig

    Wade1234 schrieb:

    i ist die anzahl der bytes, um die der zeiger erhöht werden soll

    Das ist nur bei char richtig.
    Bei Zeigerarithmetik wird auch noch die Größe vom Datentyp berücksichtigt.

    Wade1234 schrieb:

    und mit dem derefenzierungsoperator greifst du eben auf den wert an der speicherstelle zu.

    richtig



  • DirkB schrieb:

    Da ist kein Unterschied zu meinzeiger[i]. Keiner.

    Denn der Compiler wandelt das ganz von alleine um.

    das stimmt. meine persönliche meinung ist allerdings, dass meinzeiger[i] für arrays und *(meinzeiger + i) für zeigervariablen (auf dynamischen verwalteten speicher, sonst sollte man wirklich arrays benutzen) verwendet werden sollte, insbesondere dann, wenn die aufgabe ausdrücklich von zeigern spricht. rumdiskutieren mit leuten, die am längeren hebel sitzen und evtl. sogar noch über die eigene zukunft entscheiden dürfen, tut meistens nicht gut.

    Bei Zeigerarithmetik wird auch noch die Größe vom Datentyp berücksichtigt.

    ja da habe ich irgendwie das richtige gemeint und das falsche geschrieben.
    jedenfalls kannst du mit *(meinzeiger + i) wunderbar in irgendwelchen for-schleifen auf die einzelnen variablen bzw. speicherbereiche zugreifen, und wenn es sinn macht (pufferspeicher vom typ char, die int oder double enthalten z.b.), kannst du diese zeiger auch noch casten, um die anzahl der bytes, um die erhöht oder erniedrigt wird, zu verändern.



  • Wade1234 schrieb:

    meine persönliche meinung ist allerdings, dass meinzeiger[i] für arrays und *(meinzeiger + i) für zeigervariablen (auf dynamischen verwalteten speicher, sonst sollte man wirklich arrays benutzen) verwendet werden sollte, insbesondere dann, wenn die aufgabe ausdrücklich von zeigern spricht.

    Diese deine Meinung sei dir unbenommen. Teilen werden diese auffassung allerdings die wenigsten.



  • Wade1234 schrieb:

    insbesondere dann, wenn die aufgabe ausdrücklich von zeigern spricht.

    Da ist hier mehr die Änderung des Pointers gemeint.

    size_t strlen(const char *str)
    {
            size_t i;
    
            for (i = 0; *s; ++s, ++i)
              ;
    
           return i;
    }
    

    oder so

    size_t strlen(const char *str)
    {
            const char *s;
    
            for (s = str; *s; ++s)
                    ;
            return (s - str);
    }
    

Anmelden zum Antworten