Problem Bei C Hausaufgabe



  • Hey Leute,
    habe ein Problem mit der Hausaufgabe, in C99, welche in der Uni aufbekommen habe.
    Es sollte nur die Funktion bst_insert_node nicht. Ich bin echt mit meinen C Wissen am Ende.
    Würde mich wirklich über euere Antworten freuen.
    Danke schonmal im vorraus.

    Hier der Fehlercode:

    Teste bst_insert_node

    Compiliere Programm...
    Starte Programm mit valgrind...
    Programm terminitert erfolgreich
    Prüfe Speicherverwaltung
    Die Speicherverwaltung scheint OK zu sein.
    Es scheinen mehrere Einträge mit der selben Telefonnummer eingefügt zu werden!
    Der Versuch mehrere Einträge mit der selben Telefonnummer einzufügen macht den Baum kaputt!
    bst_insert_node funkiioniert _nicht_ wie erwartet!

    Mein C Code:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #include "introprog_telefonbuch.h"
    
    // Fügt einen Knoten mit der Telefonnummer phone und dem Namen name in den
    // Binären Suchbaum bst ein.  Für den Suchbaum soll die Eigenschaft gelten, dass
    // alle linken Kinder einen Wert kleiner gleich (<=) und alle rechten Kinder
    // einen Wert größer (>) haben.
    void bst_insert_node(bstree* bst, unsigned long phone, char *name)
    {
    
    	if (bst->root == NULL)
    	{
    		bst->root = (bst_node *) calloc(1, sizeof(bst_node));
            bst->root->phone = phone;
            char *Name;
            Name = (char *) calloc(strlen(name) + 1,sizeof(char));
            bst->root->name = strcpy(Name,name);
    
    	}
    	else
    	{
    		bst_node* tmp;
    		tmp = bst->root;
    
    		while(bst->root != NULL)
    		{		
    			if (phone != tmp->phone)
    			{
    				if (phone < tmp->phone)
    				{
    
    					if (tmp->left != NULL)
    					{
    						tmp = tmp->left;
    					}
    					else
    					{
    						bst_node *Phonie;
    						char *Name;
    						Phonie = (bst_node*) calloc(1, sizeof(bst_node));
    						bst->root->left = Phonie;
    						bst->root->left->phone = phone;
    						Name = (char*) calloc(strlen(name) +1,sizeof(char));
    						bst->root->name = strcpy(Name,name);
    						break;
    					}
    				}
    				if (phone > tmp->phone)
    				{
    					if (tmp->right != NULL)
    					{
    						tmp = tmp->right;
    					}
    					else
    					{
    						bst_node *Phonie;
    						char *Name;
    						Phonie = (bst_node*) calloc(1, sizeof(bst_node));
    						bst->root->left = Phonie;
    						bst->root->left->phone = phone;
    						Name = (char*) calloc(strlen(name) +1,sizeof(char));
    						bst->root->name = strcpy(Name,name);
    						break; 
    					}	
    				}
    			}	
    
    			else
    			{
    				printf("Telefonnummer schon vorhanden!");
    				return;
    			}
    
    		}
    
    	}
    
    }
    
    // Diese Funktion liefert einen Zeiger auf einen Knoten im Baum
    // mit dem Wert phone zurück, falls dieser existiert. Ansonsten wird
    // NULL zurückgegeben.
    bst_node* find_node(bstree* bst, unsigned long phone)
    {
    
    	bst_node* bsrt;		
    	bsrt = (*bst).root;
    
    	if (bst->root != NULL)								//Nicht leer
    	{
    		while(bsrt != NULL && (bsrt->phone != phone))	//Nicht leer und bsrt->phone hat ungleiche/keine phone value
    		{
    			if (bsrt->phone > phone)	
    			{
    				bsrt = bsrt->left;
    			}
    			else
    			{
    				bsrt = bsrt->right;
    			}
    		}
    	}
    
    	if (bst->root != NULL)	//Wenn nicht leer
    	{
    		return bsrt;		//Zeiger auf Knoten im Baum
    	}
    	else
    	{
    		return NULL;		//NULL wird zurückgegeben
    	}
    
    }
    
    // Gibt den Unterbaum von node in "in-order" Reihenfolge aus
    void bst_in_order_walk_node(bst_node* node)
    {
    
    	if (node != NULL)	//Wenn nicht leer
    	{
    		if(node->left != NULL)		//Wenn linker Unterbaum nicht leer
    		{
    			bst_in_order_walk_node(node->left);		//linker Unterbaum
    		}
    
    		print_node(node);			//Baum ausgabe		
    
    		if (node->right != NULL)	//Wenn rechter Unterbaum nicht leer
    		{
    			bst_in_order_walk_node(node->right);	//rechter Unterbaum
    		}
    	}
    	else
    	{
    		return;
    	}
    
    }
    
    // Gibt den gesamten Baum bst in "in-order" Reihenfolge aus. Die Ausgabe
    // dieser Funktion muss aufsteigend soriert sein.
    void bst_in_order_walk(bstree* bst)
    {
        if (bst != NULL)	//Wenn nicht leer
        {
            bst_in_order_walk_node(bst->root);	//"in-order" Reihnfolge ausgegeben
        }
    }
    
    // Löscht den Teilbaum unterhalb des Knotens node rekursiv durch
    // "post-order" Traversierung, d.h. zurerst wird der linke und dann
    // der rechte Teilbaum gelöscht. Anschließend wird der übergebene Knoten
    // gelöscht.
    void bst_free_subtree(bst_node* node)
    {
    	if (node->left != NULL)		//Wenn linker Teilbaum nicht schon leer
    	{
    		bst_free_subtree(node->left);	//Linker Baum wird befreit
    	}
    	if (node->right != NULL)	//Wenn rechter Teilbaum nicht schon leer
    	{
    		bst_free_subtree(node->right);	//Linker Baum wird befreit
    	}
    	if (node == NULL)			//Wenn Baum schon leer
    	{
    		return;
    	}
    
    	free(node);			//Als letzes wird der übergebene Knoten gelöscht
    
    }
    
    // Löscht den gesamten Baum bst und gibt den entsprechenden Speicher frei.
    void bst_free_tree(bstree* bst)
    {
        if(bst != NULL && bst->root != NULL)	//Wenn nicht schon leer und frei
        {
            bst_free_subtree(bst->root);	//Gibt Speicher frei
            bst->root = NULL;				//Löscht den gesamten Baum
        }
    }
    

    Hier das Struct:

    #include <stdio.h>
    #include <stdlib.h>
    
    #define MAX_STR 255
    #define DOT_NODETYPE bst_node
    #define DOT_RCHILD right
    #define DOT_LCHILD left
    #define DOT_PARENT parent
    #define DOT_KEY phone
    #define DOT_VALUE name
    
    /* typedefs, damit wir uns das "struct" sparen können.
     */
    typedef struct bst_node bst_node;
    typedef struct bstree  bstree;
    
    /* Knoten im Binären Suchbaum, wobei ...
     * - left und right das linke bzw. rechte Kind spezifiziert.
     * - parent auf denjenigen Knoten verweist, dessen Kind dieser Knoten ist.
     * - phone die Telefonnummer des Suchbaumknotens angibt.
     * - name den entsprechenden Namen des Suchbaumknotens angibt.
     */
    struct bst_node
    {
        bst_node* left;
        bst_node* right;
        bst_node* parent;
        unsigned long phone;
        char *name;
    };
    
    /* Ein Binärer Suchbaum mit einem Wurzelknoten root und der Anzahl an
     * Elementen im Baum.
     */
    struct bstree
    {
        struct bst_node* root;
        int count;
    };
    
    /* Hilfsstrucktur für open_file / read_line / close_file
     */
    typedef struct  {
        FILE *filepointer;
        char *line;
        size_t linecapp;
    } read_line_context;
    
    void bst_insert_node(bstree* bst, unsigned long phone, char *name);
    bst_node* find_node(bstree* bst, unsigned long phone);
    void bst_in_order_walk(bstree* bst);
    void bst_free_tree(bstree* bst);
    void open_file(read_line_context *ctx, const char *filename);
    void open_stdin(read_line_context *ctx);
    int read_line(read_line_context *ctx, char **operation, unsigned long* nummer, char **name);
    void close_file(read_line_context *ctx);
    void print_to_dot(DOT_NODETYPE* tree, char* filename);
    void print_node(bst_node *node);
    

  • Mod

    Die Aufgabenstellung ist ja anscheinend, dass dein Programm auch mit mehreren gleichen Telefonnummern zurechtkommen soll. Derzeit wirft es eine Fehlermeldung. Das ist wohl nicht das gewünschte Verhalten.

    Wer Integer für Telefonnummern nimmt, gehört übrigens sofort standrechtlich erschossen, ohne Chance auf Einspruch oder Gnade.



  • SeppJ schrieb:

    Die Aufgabenstellung ist ja anscheinend, dass dein Programm auch mit mehreren gleichen Telefonnummern zurechtkommen soll. Derzeit wirft es eine Fehlermeldung. Das ist wohl nicht das gewünschte Verhalten.

    Dass das nicht das gewünschte Verhalten ist erklärt sich von selbst. Allerdings ist in Zeile 24 eine if-Bedingung die genau das abfangen soll. Trotzdem entsteht dieser Fehler, die frage ist warum.

    SeppJ schrieb:

    Wer Integer für Telefonnummern nimmt, gehört übrigens sofort standrechtlich erschossen, ohne Chance auf Einspruch oder Gnade.

    Sie werden ja als unsigned long definiert.


  • Mod

    Du hast rein gar nichts von meiner Antwort verstanden. Sie kommt mir eigentlich recht verständlich vor. Vielleicht war es nicht verständlich genug, vielleicht hast du nicht über sie nachgedacht. Ich tippe eher auf letzteres.



  • UniStudent69 schrieb:

    SeppJ schrieb:

    Wer Integer für Telefonnummern nimmt, gehört übrigens sofort standrechtlich erschossen, ohne Chance auf Einspruch oder Gnade.

    Sie werden ja als unsigned long definiert.

    achso ja dann ist ja alles gut. 🙄



  • also was ich sagen wollte: es könnte ja sein, dass man mit telefonnummern rechnen möchte, aber bei der multiplikation sollte es dann unsigned long long int sein, damit da kein überlauf entsteht.

    aufgabe: multiplizieren sie die telefonnummer von herrn müller mit der telefonnummer von frau schulze. 😃



  • Wie unterscheidest du eine Nummer aus Berlin (Vorwahl 030) mit einer aus Griechenland (0030)?



  • Wieso bei bst->root->left einfügen?
    Wofür hast du tmp ?
    Baut sich überhaupt ein Baum auf?

    Minimalbeispiel das den "Fehler" zeigt?



  • DirkB schrieb:

    Wie unterscheidest du eine Nummer aus Berlin (Vorwahl 030) mit einer aus Griechenland (0030)?

    Das ist natürlich beides Griechenland ... +30... 🕶 🤡



  • Swordfish schrieb:

    DirkB schrieb:

    Wie unterscheidest du eine Nummer aus Berlin (Vorwahl 030) mit einer aus Griechenland (0030)?

    Das ist natürlich beides Griechenland ... +30... 🕶 🤡

    Wenn da immer die internationale Vorwahl dabei ist, komst man bei einigen Mobilrufnummern in Deutschland auf 13 (Dezimal) Stellen.
    Dafür werden mindestens 43 Bit gebraucht.

    International sind auch 15 Ziffern gültig.

    Dann machen wir auf 64-Bit-Linux weiter. das passt das dann in ein long 👍
    :p



  • DirkB schrieb:

    Dann machen wir auf 64-Bit-Linux weiter. das passt das dann in ein long 👍
    :p

    Siehst? Lässt sich alles lösen 👍 🤡


Anmelden zum Antworten