String als struct mit Funktionen, jedoch wird mit (null) ausgegeben



  • Guten Tag liebe C Community,

    ich habe folgendes Problem.
    Ich muss für die UNI eine Aufgabe machen, welche Strings als struct implementiert und durch die Funkionen sollen die Strings unter anderem kopiert und ausgegeben werden.

    Jedoch wird mir, wenn ich die Print-Funkion durchführe nur : (null)(null)(null) ausgegeben und nicht der String an sich.

    Danke schonmal im Voraus.

    Anbei ist der Quellcode:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    typedef struct {
    
    	int len;
    	char *s;
    
    }
    string_a;
    
    typedef string_a* string;
    void set (string* s1, char *s)
    {
    	int len_a = 0;
    	string pNeu = NULL;
    	char *pstrNeu = NULL;
    
    	if ( s==0 )
    	{
    		s = "";
    	}
    	if ( *s1==NULL )
    	{
    		pNeu = calloc (sizeof (string_a), sizeof (char));
    		if ( pNeu==0 )
    		{
    			return;
    		}
    		*s1 = pNeu;
    		(*s1)->s = pstrNeu;
    	}
    	len_a = strlen (s) +1;
    
    	if ((*s1)-> len == len_a )
    	{
    		strcpy ((*s1)->s, s);
    	}
    	else
    	{
    		free ( pstrNeu );
    
    		pstrNeu = calloc ( len_a, sizeof (char) );
    		if ( pstrNeu ==NULL )
    		{
    			return;
    		}
    	}
    }
    void copy (string* s1, string s2){
    
    }
    
    void print (string s1){
    
    	printf ("%s",s1->s);
    }
    
    
    int main(void) {
    
    string s1=NULL, s2=NULL, s3=NULL, s4=NULL, s5=NULL;
    
    setvbuf(stdout, NULL, _IONBF, 0);
    setvbuf(stderr, NULL, _IONBF, 0);
    
    printf ("==============Testen von set() und copy()===========\n");
    
    set (&s1, NULL);
    set (&s2, "Hallo Welt!");
    set (&s3, "Killroy is watching you!");
    copy (&s4, s2);
    copy (&s5, s3);
    
    print (s1);
    print (s2);
    print (s3);
    print (s4);
    print (s5);
    
    }
    


  • Sieh mal hier: https://www.c-plusplus.net/forum/topic/352117/printen-eines-structs-mit-unterprogramm
    Da kam vorgestern dieselbe Frage. Macht ihr denselben Kurs?

    Alles wesentliche wurde dort gesagt.

    Ist das so der vorgegebene Code? Also mit einer set-Funktion, die eine eierlegende Wollmilchsau sein soll?



  • @wob Das ist bis auf ein paar Variablennamen in set() 1:1 der selbe Code ...



  • @wob @Swordfish

    Ja genau der ist vorgegeben, man darf aber die set Funktion ändern.



  • @wob ja habe es gerade gesehen, danke dir aber kenn ihn nicht.



  • @Stabilo sagte in String als struct mit Funktionen, jedoch wird mit (null) ausgegeben:

    Ja genau der ist vorgegeben, man darf aber die set Funktion ändern.

    Dann zeig bitte den vorgegebenen Code so wie Du ihn bekommen hast ohne Änderungen und die genaue Aufgabenstellung.



  • @Swordfish

    Der vorgegebene Code ist 1zu1 genauso, nur die set Funktion nicht, bei der steht nur:

    void set (string* s1, char *s);

    Aufgabe von der set Funktion soll sein, die Strings (Speicherplatz) dynamisch zu verwalten.



  • #include <assert.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    typedef struct {
        size_t len;
        char *s;
    } *string;  // don't do that!
    
    void set(string *s1, char *s)
    {
        assert(s1);  // sanity check
    
        if (!(*s1)) { // string doesn't exist -> create
            *s1 = calloc(1, sizeof(**s1));  // reserve memory and set zero
            if (!(*s1))  // calloc failed -> bail out
                return;
        }
    
        if (!s)
            s = "";  // assume empty string
    
        free((*s1)->s);
        size_t length = strlen(s);
        (*s1)->s = malloc(length + 1);
        if (!(*s1)->s)  // malloc failed -> bail out
            return;
    
        strcpy((*s1)->s, s);
        (*s1)->len = length;
    }
    
    void copy(string* s1, string s2)
    {
        assert(s1 && s2);
    
        set(s1, s2->s);  // copy == set
    }
    
    void print(string s1)
    {
        printf("%s", s1->s);
    }
    
    void free_string(string *s1)
    {
        assert(s1);
        
        if (!(*s1))
            return;
    
        free((*s1)->s);
        free(*s1);
    }
    
    int main()
    {
        string s1 = NULL, s2 = NULL, s3 = NULL, s4 = NULL, s5 = NULL;
    
        setvbuf(stdout, NULL, _IONBF, 0);
        setvbuf(stderr, NULL, _IONBF, 0);
    
        puts("==============Testen von set() und copy()===========");
    
        set(&s1, NULL);
        set(&s2, "Hallo Welt!");
        set(&s3, "Killroy is watching you!");
        copy(&s4, s2);
        copy(&s5, s3);
    
        print(s1);
        print(s2);
        print(s3);
        print(s4);
        print(s5);
    
        // free memory!
        free_string(&s5);
        free_string(&s4);
        free_string(&s3);
        free_string(&s2);
        free_string(&s1);
    }
    


  • @Swordfish
    Danke dir, hast mir echt sehr weiter geholfen.
    Hätte nur eine frage zu einem Befehl, was genau macht "assert" ?



  • @Stabilo assert prüft die Übergebene Bedingung.
    Wenn diese 0 (falsch) ist, wird das Programm mit einer Meldung abgebrochen.

    http://www.cplusplus.com/reference/cassert/assert/?kw=assert



  • Aber nur im Debug-Modus. Daher sollte das Programm dann zuerst im Debug-Modus getestet werden, bevor eine Release-Version davon veröffentlicht wird (besser wären natürlich noch zusätzliche Unit-Tests, welche auch im Release-Modus ausgeführt werden).



  • @DirkB @Th69

    Okay alles klar, danke euch.


Log in to reply