Programmierhilfe für Studium gesucht - C



  • Die Aufgabenstellung ist eigentlich völlig klar. Was verstehst du daran nicht?



  • Es fehlt übrigens eine Freigabefunktion, damit man die (normalerweise implizite) Anforderung "Achten Sie darauf, dass kein Platz verloren geht!" umsetzen kann. Ich schlage void release(string s); vor.



  • Bashar schrieb:

    Ich schlage void release(string s); vor.

    Ein

    set(s, NULL);
    

    sollte auch gehen



  • Oh, stimmt.



  • Muss ich nicht vor dem int main () folgendes programmieren?
    void set (string* s1, char *s); /* initialisiere s1 mit s /
    void copy (string
    s1, string s2); /* kopiere s2 nach s1 /
    void concat (string
    s1, string s2); /* hänge s2 an s1 an /
    void print (string s1); /
    drucke s1 aus */

    Und wenn ich zum beispiel das void set (...) machen will... Wie initialiesiere ich denn s1 mit s?
    Muss ich da erst die Länge vom string festlegen und den pointer auf den Anfang draufsetzen???



  • Paul_McIcetea schrieb:

    Muss ich nicht vor dem int main () folgendes programmieren?

    "Muss" nicht, aber eine sinnvolle Möglichkeit ist es schon.

    Und wenn ich zum beispiel das void set (...) machen will... Wie initialiesiere ich denn s1 mit s?

    Du schaust wie lang s ist, dann besorgst du ausreichend Speicher (➡ malloc) und kopierst den Inhalt von s dort rein.



  • Verdammt!
    Die bekloppten Vorgaben machen das nicht so trivial, wie es anfangs aussieht.

    Ich würde die Vorgabe len==-1, wenn str==NULL kippen. Handelt man sich nur Ärger mit ein.



  • ...oder man nimmt sich doch eine string_alloc() und eine string_free() Funktion hinzu.
    Vielleicht das Beste...



  • Bashar schrieb:

    Du schaust wie lang s ist, dann besorgst du ausreichend Speicher (➡ malloc) und kopierst den Inhalt von s dort rein.

    kann ich das so oder wenigstens so ähnlich machen?

    int laenge=strlen(s); //länge von s
    s1=(string*) malloc(sizeof(string_t));
    strcpy(s,s1); //kopiere s in s1



  • Das Ergebnis von malloc braucht man nicht casten.
    sizeof(string_t) ist nicht das, was du willst. Du willst so viel Speicher, dass s reinpasst. Also, eben so viel wie dir strlen zurückgegeben hat, plus 1 für '\0' am Ende.



  • Paul_McIcetea schrieb:

    int laenge=strlen(s); //länge von s
    s1=(string*) malloc(sizeof(string_t));
    strcpy(s,s1); //kopiere s in s1

    Bitte poste genügend Kontext dazu, dass man die Typen der Variablen usw. erkennen kann. Ist s1 ein string, ein string*, oder ein char*?



  • #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    #include <string.h>

    typedef struct {
    int len; /* Anzahl der Zeichen in s; -1 wenn s == NULL */
    char *s; /* ein C-string mit abschließendem \0-Zeichen */
    } string_t;

    typedef string_t* string;

    void set (string* s1, char *s) /* initialisiere s1 mit s */
    {

    int laenge=strlen(s); //länge von s
    s1=(string*) malloc(sizeof(laenge));
    strcpy(s,s1);
    }
    soweit wäre ich jetzt... s1 wäre dann also ein string* (vorgegeben)

    Mechanics schrieb:

    sizeof(string_t) ist nicht das, was du willst. Du willst so viel Speicher, dass s reinpasst. Also, eben so viel wie dir strlen zurückgegeben hat, plus 1 für '\0' am Ende.

    wäre das dann so besser?
    s1=(string*) malloc(sizeof(laenge));



  • int laenge=strlen(s); //länge von s
    s1=(string*) malloc(sizeof(string_t));  // du brauchst keinen Platz für string_t sondern für s. Die Laenge hast du gerade fast bestimmt.
    strcpy(s,s1); // Beachte die Reihenfolge bei strcpy ²
    

    Bei strcpy(z,q) soll das so aussehen, als ob man z = q schreibt.



  • Paul_McIcetea schrieb:

    void set (string* s1, char *s) /* initialisiere s1 mit s */
    	{
    
    		int laenge=strlen(s); //länge von s
    		s1=(string*) malloc(sizeof(laenge));
    		strcpy(s,s1);
            }
    

    soweit wäre ich jetzt... s1 wäre dann also ein string* (vorgegeben)

    OK. Mechanics hat schon die malloc-Zeile kritisiert.

    Ein paar Sachen: 1) Du solltest nochmal nachlesen, welches Argument bei strcpy die Quelle und welche das Ziel ist.
    2) Du tust so, als wäre s1 ein char-Zeiger. Völliger Unsinn, s1 zeigt auf einen string (was auch wieder ein Zeiger auf struct string_t ist). Du kannst da nicht einfach irgendwelches Zeug reinkopieren. Das Ziel deiner Kopieraktion ist das Element (*s1)->s .

    Mechanics schrieb:

    wäre das dann so besser?
    s1=(string*) malloc(sizeof(laenge));

    Das +1 für das Nullbyte am Ende fehlt immernoch. Außerdem (siehe oben) ist es falsch, das ganze an s1 zuzuweisen. Und mach den Cast weg.

    edit: thx an furble wurble, habs korrigiert.
    BTW, warum wird an set und die anderen Funktionen eigentlich ein string -Zeiger übergeben? Das scheint mir nicht sonderlich sinnvoll zu sein.



  • Bashar schrieb:

    s1 zeigt auf eine gegebene Struktur vom Typ struct string_t .

    s1 ist sogar string_t**



  • sizeof liefert dir Größe (den Speicherverbrauch) in Bytes von einer Variablen.

    laenge ist vom Typ int und das sind i.A. 16 - 32 Bit also 2 - 4 Byte
    Du brauchst den Wert von laenge

    Falls du auf dumme Gedanken kommst:
    s ist ein Zeiger und die sind z.B. auf 32-Bit Systemen auch 4 Byte groß.
    Das hat nichts mit der Länge des Textes zu tun, auf die s zeigt.



  • Also erstmal danke an euch alle, dass ihr euch die Zeit genommen habt, um mir zue helfen.
    Aber das mit dem Programmieren wird wohl bis Freitag nichts bei mir...
    Ich kann euch ja nichtmals erklären, woran es bei mir scheitert.

    Also Vielen Dank an alle, aber ich muss mir irgendwo jemanden suchen, ders mir programmiert und erklärt



  • Dabei ist das nicht mal eine schwere Aufgabe, wie lange studierst du denn schon?



  • Seit Oktober...
    Aber in den Vorlesungen lernt man bei unserem Dozent nichts und in den 3-4 Übungsstunden, die wir hatten, haben wir ganz andere Sachen gemacht.
    Und ich finde es ziemlich schwer sich das alles in der kurzen Zeit selbst beizubringen, wenn man auch noch andere Fächer hat...



  • Ja zum lernen ist ein Forum nicht so geeignet.

    Deine Versuche gestern liessen bei mir ein wenig den Eindruck aufkommen, dass Du Deine Vorschläge gar nicht testen kannst.
    Dem ist aber nicht so? Du hast einen Compiler zu Deiner Verfügung?

    Ich denke bis Freitag würdest Du das hinbekommen - mit viel Initiative.
    Aber in kleinen Schritten hätten wir Dich schon dahin gebracht.
    (Als erstes hättest Du aber die Code-Tags (der C Button unter dem Editierfeld) entdecken müssen. 😉 )

    Die Aufgabe ist nicht so trivial, wie sie scheint. (Oder ich habe Tomaten auf den Augen...)
    Mein Anfang - nur für den leeren String - steht unten.

    Ist das Verständlich?
    Versuch Dich nochmal an der set() Funktion!
    Der Einfachheit halber benutz folgenden Prototypen:

    void string_set(string s1, char *s);
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdbool.h>
    
    typedef struct {
      int len; /* Anzahl der Zeichen in s; -1 wenn s == NULL */
      char *s; /* ein C-string mit abschließendem \0-Zeichen (oder NULL) */
    } string_t;
    
    typedef string_t* string;
    
    string string_alloc()
    {
      string s = malloc(sizeof(string_t));
      if (s!=NULL)
        {
          // initialisieren nach Vorgabe
          s->len = -1;
          s->s   = NULL;
        }
      return s;
    }
    
    void string_free(string s)
    {
      // nicht der NULL Zeiger?
      if (s!=NULL)
        {
          // Speicher fuer einen cstring alloziert?
          if (s->s!=NULL)
            free(s->s); // dann den cstring freigeben
          free(s); // das gesamte string_t Objekt freigeben
        }
    }
    
    // die Bedingungen testen
    bool is_valid(string s)
    {
      if(s->s==NULL)
        return s->len==-1; // wenn s==NULL, dann len==-1
      return true; // ueber "gefuellte" strings koennen wir noch keine Aussage machen
    }
    
    int main(void)
    {
      string s = string_alloc();
      if(!is_valid(s))
        puts("Fehler!\n");
      string_free(s);
    }
    

Anmelden zum Antworten