Verkettete Liste (Suche)



  • Ich würde mal meinen Code posten wollen.
    @Hartmut 1164 - Danke für den Code! Aber ich verliere irgendwie die Überischt. Versuche es so einfach wie möglich zu machen.

    Hier der Code:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <malloc.h>
    #include <conio.h>
    
    #define MAX 21
    
    struct student
    {	
    	char nachname[MAX];
    	char vorname[MAX];
    	int matrikel;
    	struct prufung *first;
    };
    
    struct prufung
    {
    	char veranstaltung[MAX];
    	int punkte;
    	char datum[MAX];
    	char professor[MAX];
    	struct prufung *next;
    };
    
    typedef struct student student_t;
    typedef struct prufung prufung_t;
    
    int einfugenPrufung(char *veranstaltung, int punkte, char *datum, char *professor, prufung_t **start_pointer);
    void prufungAusgeben(prufung_t *start_pointer);
    struct prufung *nameSuchen(char *name, prufung_t *start_pointer);
    struct prufung *punkteSuchen(int punkte, prufung_t *start_pointer);
    void listeSpeichern(prufung_t *start_pointer);
    void listeLesen(void);
    
    int main(void)
    {
    	char nachname[MAX];
    	char vorname[MAX];
    	int matrikel;
    
    	char veranstaltung[MAX];
    	int punkte;
    	char datum[MAX];
    	char professor[MAX];
    
    	struct student *str = NULL;
    	struct prufung *ptr = NULL;
    	struct prufung *start_pointer = NULL;
    
    	printf("\nWollen Sie Daten aus der liste.dat lesen [j/n]?");
    	if(getch() == 'j')
    		listeLesen();
    
    	printf("\n\n");
    	printf("Geben Sie einen Studenten ein:\n");
    	printf("==============================\n");
    
    	printf("\nNachname   : ");
    	scanf("%s", nachname);
    
    	printf("Vorname    : ");
    	scanf("%s", vorname);
    
    	printf("MatrikelNr.: ");
    	scanf("%d", &matrikel);
    
    	if( (str = (struct student*)malloc(sizeof(struct student))) == NULL)
    		return 1;
    	else
    	{
    		strcpy(str->nachname, nachname);
    		strcpy(str->vorname, vorname);
    		str->matrikel = matrikel;
    	}
    
    	printf("\n+-----------------------------------+");
    	printf("\nWollen Sie Pruefungen eingeben [j/n]?\n");
    
    	if(getch() == 'j')
    	{
    		do
    		{
    			printf("\nVeranstaltung: ");
    			scanf("%s", veranstaltung);
    
    			printf("Punkte: ");
    			scanf("%d", &punkte);
    
    			printf("Datum [TTMMJJJJ]: ");
    			scanf("%s", datum);
    
    			printf("Professor: ");
    			scanf("%s", professor);
    
    			if(einfugenPrufung(veranstaltung, punkte, datum, professor, &start_pointer) != 0)
    			{
    				printf("\nFehler beim Hinzufuegen einer Pruefung");
    				return 1;
    			}		
    			printf("\nWollen Sie weitere Pruefungen eingeben [j/n]?\n");
    		}
    		while(getch() == 'j');
    
    		prufungAusgeben(start_pointer);
    	}
    
    	printf("\n+-----------------------------------+");
    	printf("\n\nSuche nach 'Veranstaltung': ");
    	scanf("%s", veranstaltung);
    
    	if( (ptr = nameSuchen(veranstaltung, start_pointer)) == NULL )
    		printf("\nVeranstaltung mit Namen %s nicht vorhanden!", veranstaltung);
    	else
    	{
    		printf("\nDie Veranstaltung: %s", ptr->veranstaltung);
    		printf("\nDie Punkte       : %d", ptr->punkte);
    		printf("\nDas Datum        : %s", ptr->datum);
    		printf("\nDer Professor    : %s", ptr->professor);
    	}
    
    	printf("\n+-----------------------------------+");
    	printf("\n\nSuche nach Punkten: ");
    	scanf("%d", &punkte);
    
    	if( (ptr = punkteSuchen(punkte, start_pointer)) == NULL )
    		printf("\nPruefung mit Punkte kleiner als: %d nicht vorhanden", punkte);
    	else
    	{
    		printf("\nDie Veranstaltung: %s", ptr->veranstaltung);
    		printf("\nDie Punkte       : %d", ptr->punkte);
    		printf("\nDas Datum        : %s", ptr->datum);
    		printf("\nDer Professor    : %s", ptr->professor);
    	}
    
    	printf("\n+-----------------------------------+");
    	printf("\nWollen Sie die Liste Speichern [j/n]?");
    	if(getch() == 'j')
    		listeSpeichern(start_pointer);	
    	else
    		printf("\nEs werden keine Daten gespeichert!");
    
    	free(str);
    	free(ptr);	
    
    	printf("\n\n");
    	return 0;
    }
    
    int einfugenPrufung(char *veranstaltung, int punkte, char *datum, char *professor, prufung_t **start_pointer)
    {
    	struct prufung *ptr = NULL;
    
    	if( (ptr = (struct prufung*)malloc(sizeof(struct prufung))) == NULL )	
    		return 1;
    	else
    	{
    		strcpy(ptr->veranstaltung, veranstaltung);
    		ptr->punkte = punkte;
    		strcpy(ptr->datum, datum);
    		strcpy(ptr->professor, professor);
    		ptr->next = *start_pointer;
    		*start_pointer = ptr;
    
    		return 0;
    	}
    }
    
    void prufungAusgeben(prufung_t *start_pointer)
    {
    	struct prufung *ptr = start_pointer;
    
    	printf("\n\n+-----------------------------------+");
    	printf("\nAusgabe der Pruefungen eines Studenten:\n");
    	while(ptr != NULL)
    	{	
    		printf("\nVeranstaltung: %s", ptr->veranstaltung);
    		printf("\nPunkte       : %d", ptr->punkte);
    		printf("\nDatum        : %s", ptr->datum);
    		printf("\nProfessor    : %s", ptr->professor);
    		printf("\n");
    		ptr = ptr->next;
    	}
    }
    
    struct prufung *nameSuchen(char *name, prufung_t *start_pointer)
    {
    	struct prufung *ptr = start_pointer;
    
    	while(ptr != NULL && strcmp(ptr->veranstaltung, name))
    		ptr = ptr->next;
    
    	return ptr;
    }
    
    struct prufung *punkteSuchen(int punkte, prufung_t *start_pointer)
    {
    	struct prufung *ptr = start_pointer;
    
    	while(ptr != NULL && (ptr->punkte < punkte) )
    		ptr = ptr->next;	
    
    	return ptr;
    }
    
    void listeSpeichern(prufung_t *start_pointer)
    {
    	FILE *file;
    	prufung_t *ptr;
    
    	file = fopen("liste.dat", "wb");
    	if(file == NULL)
    	{
    		perror("Fehler beim Oeffnen");
    		exit(EXIT_FAILURE);
    	}
    
    	fseek(file, 0, SEEK_END);
    
    	ptr = start_pointer;
    
    	while(ptr != NULL)
    	{
    		fwrite(ptr, sizeof(prufung_t), 1, file);
    		ptr = ptr->next;
    	}
    
    	fclose(file);
    }
    
    void listeLesen(void)
    {
    	FILE *file;
    	prufung_t ptr;
    
    	file = fopen("liste.dat", "rb");
    	if(file == NULL)
    	{
    		perror("\nFehler beim Oeffnen");
    		getch();
    		main();		
    	}
    
    	while(fread (&ptr, sizeof(prufung_t), 1, file) == 1)
    	{
    		printf("\n+-----------------------------------+");
    		printf("\nDie Pruefungen sind:");
    		printf("\n");
    		printf("\nVeranstaltung: %s", ptr.veranstaltung);
    		printf("\nPunkte       : %d", ptr.punkte);
    		printf("\nDatum        : %s", ptr.datum);
    		printf("\nProfessor    : %s", ptr.professor);		
    	}	
    	fclose(file);
    }
    

    Könnte ich die Suche nach den Punkten in meiner Funktion nicht verändern, anstatt neuen struct zu machen?
    Ein anderes Problem habe ich auch noch. Wenn ich die Liste abspeichern will (als Binärdatei) dann gibt er mir eine Fehlermeldung aus. Aber er speichert trotzdem.
    Ich kann die Daten auch wieder laden und sie werden auch angezeigt. Beim nächsten Speichern (also beim Anhängen) bekomme ich keine Fehlermeldung.

    Danke schonmal!
    Schönen Gruß
    Manda



  • Meh, da sind ein paar böse Fehler im Code 😉
    Ich hab nicht alles gelesen, aber das:

    if(file == NULL)
        {
            perror("\nFehler beim Oeffnen");
            getch();
            main();       
        }
    

    ist eine indirekte Rekursion und ich glaube nicht das du das an der Stelle willst!
    Du rufst dort die main()-Funktion auf ohne die andere Funktion beendet zu haben.
    Anstelle main() sollte da ein return stehen, ohne einen Wert da du ja void hast.
    Der Fehler fiel mir gerade ins Auge, den Rest des Codes habe ich (noch) nicht gelesen.

    Ansonsten würde ich es wie es auch schonmal Vorgeschlagen wurde mit einer 2. Liste machen in die alle gefundenen Einträge eingetragen werden. Dann wird diese Liste zurück gegeben...



  • Statt nun fuer jeden Suchparameter eine Funktion zu schreiben, mach doch folgendens:

    struct PrufungList *BuildSearchResults (int (*Found (Prufung   *pPrufung,
                                                         void      *pCriterium))
    {
    
        Prufung     *pCurrent;
        PrufungList *pReturn       = NULL,
                    *pCurrentList  = NULL,
                    *pTemp;
    
        pCurrent = pPrufung;
    
        while (pCurrent != NULL)
        {
            if (Found (pCurrent, pCriterium) == 0)
            {
                pTemp = NewList (pCurrent);
                if (pReturn == NULL)
                    pReturn = pTemp;
                else
                {
                    pTemp->pBefore = pCurrentList;
                    pCurrentList->pNext = pNext;
                }
    
                pCurrentList = pTemp;
            }
    
            pCurrent = pCurrent->pNext;
        }
    
        return pReturn;
    }
    

    Dann brauchst Du die Verwaltung der Liste der Ergebnisse nur einmal zu schreiben und das Suchkriterium mittels der Uebergabe der entsprechenden Funktion bestimmen.



  • @Skalli, danke für den Hinweis. Wollte eigentlich damit wieder in main() zurück. Aber habe jetzt ein "return" drin.
    @Hartum, ich müsste eigentlich nur für diese beiden Kriterien was suchen. Aber deine Funktion scheint universeller. Ich probier es mal. Hoffe das ich den Überblick nicht langsam verlieren 🙂

    Danke!



  • @Hartmut - Bin gerade dabei deine Funktion zu implementieren. Aber irgendwie kriege ich komische Fehlermeldungen, wie:
    - inkompatible typen (in Funktion: *BuildSearchResult, im else-Zweig)
    - undeclared identifier (in der gleichen Funktion, bei: pCurrent = pPrufung; )
    Ich glaube er erkennt die parameterliste nicht.
    Hoffe du kannst mir da noch malhelfen 🙂

    Danke.



  • War frueh am morgen:

    struct PrufungList *BuildSearchResults (Prufung   *pPrufung, void *pCriterium,int (*Found (Prufung   *pCurrentIn, void  *pCriterium)))
    {
    //...
    


  • @Harmut - Im else Zweig zeigt er immer "kompatibilitäts-Probleme" an. Die ich nicht verstehe. Ich habe stattdessen, eine andere variante versucht, die auch zu funktionieren scheint.
    Undzwar folgende:

    struct prufung *punkteSuchen(int punkte, prufung_t *start_pointer)
    {
    	struct prufung *ptr = start_pointer;
    
    	while(ptr != NULL)
    	{
    		if(ptr->punkte < punkte)
    		{
    			printf("\n");
    			printf("\nVeranstaltung: %s", ptr->veranstaltung);
    			printf("\nDatum        : %s", ptr->datum);
    			printf("\nPunkte       : %d", ptr->punkte);
    			printf("\nProfessor    : %s", ptr->professor);				
    		}
    		ptr = ptr->next;
    	}	
    	return ptr;
    }
    

    Habe nur diese Funktion umgeändert, einfach ein if rein und es klappt.
    Was allerdings nicht geht und ich aber haben muss ist folgendes:
    Wenn man die Datei abspeichert und dann neustartet. Diesmal aber gleich von der Datei liest. Dann zeigt er auch die Daten an.
    Ich kann allerdings nichts dadrin suchen. Wenn ich eine Veranstaltung suche oder Punkte suche, dann sagt er, es gibt nichts.
    Eigentlich sollte er die Daten ja ausgeben, die da drin sind.

    Hat jemand da eine idee? Oder mache ich was falsch?



  • Hallo Leute, das Problem hat sich erledigt. Ich kann jetzt auch von der Liste die Daten suchen lassen. Funktioniert soweit alles.
    Hätte da noch eine Frage zum struct tm (muss das Datum dadurch einlesen).
    Ich geb mal den Code vor:
    Mein Struct:

    struct prufung
    {
    	char veranstaltung[MAX];
    	int punkte;
    	char datum[MAX];
    	char professor[MAX];
    	struct prufung *next;
    };
    

    Hier lese ich die Prüfungen ein:

    do
    		{
    			printf("\nVeranstaltung: ");
    			scanf("%s", veranstaltung);
    
    			printf("Punkte: ");
    			scanf("%d", &punkte);
    
    			printf("Datum [TTMMJJJJ]: ");
    			scanf("%s", datum);
    
    			printf("Professor: ");
    			scanf("%s", professor);
    
    			if(einfugenPrufung(veranstaltung, punkte, datum, professor, &start_pointer) != 0)
    			{
    				printf("\nFehler beim Hinzufuegen einer Pruefung");
    				return 1;
    			}		
    			printf("\nWollen Sie weitere Pruefungen eingeben [j/n]?\n");
    		}
    		while(getch() == 'j');
    

    Ich hab jetzt einfach nur ein char-array für das Datum genommen. Wollte erstmal nur, dass es läuft.
    Nun zum Problem:
    Das datum soll in dieser Form angegeben werden: Datum[TTMMYYYY]: 01022009
    In der Ausgabe soll es aber Konvertiert werden, so: 01.02.2009
    Wie kriege ich das mit dem struct tm hin?

    Hier die Ausgabe:

    void prufungAusgeben(prufung_t *start_pointer)
    {
    	struct prufung *ptr = start_pointer;
    
    	printf("\n\n+-----------------------------------+");
    	printf("\nAusgabe der Pruefungen eines Studenten:\n");
    	while(ptr != NULL)
    	{	
    		printf("\nVeranstaltung: %s", ptr->veranstaltung);
    		printf("\nPunkte       : %d", ptr->punkte);
    		printf("\nDatum        : %s", ptr->datum);
    		printf("\nProfessor    : %s", ptr->professor);
    		printf("\n");
    		ptr = ptr->next;
    	}
    }
    

    Kann mir jemand mit dem struct tm helfen??

    Danke schonmal!
    Gruß
    Manda



  • Problem hat sich erledigt. Danke für die Hilfe Jungs!

    Schöne Grüße
    Manda



  • hallo, ich bin grad am Versuch die verkettete liste aus meinem folgenden Beispiel nachzuvollziehen. mittlerweile scheitere ich schon an den einfachsten Passagen. Kann mir jemand wirklich von Anfang an und für jede Zeile (auch unter main()) erklären, was geschieht und welche Werte nun in den Handles drinstehen ? Ich wäre sehr dankbar:
    das listing:

    #include "stdafx.h"

    using namespace System;

    //die Struktur für den verwalteten Heap
    ref struct beispiel {
    int inhalt;
    beispiel ^next;

    };

    void einfuegen(int inhaltneu, beispiel ^anfang) {

    beispiel ^zeiger;
    zeiger=anfang;

    while (zeiger->next!=nullptr) {
    zeiger=zeiger->next;
    }

    zeiger->next=gcnew beispiel;
    zeiger=zeiger->next;
    zeiger->inhalt=inhaltneu;

    }
    void ausgabe(beispiel ^anfang) {
    beispiel ^zeiger;
    zeiger=anfang;
    Console::WriteLine("{0}", zeiger->inhalt);

    while (zeiger->next != nullptr) {
    zeiger = zeiger->next;
    Console::WriteLine("{0}", zeiger->inhalt);
    }

    }

    int main(array<System::String ^> ^args)
    {

    beispiel ^anfang;

    anfang=gcnew beispiel;
    anfang->inhalt=0;

    for (int schleife=1;schleife<5;schleife++) {
    einfuegen(schleife, anfang);

    }

    ausgabe(anfang);

    return 0;
    }
    😞 😞



  • Dein Beitrag gehört in C++/CLI Forum.
    Hoffentlich wird er bald verschoben.
    Simon

    Edit
    Hier gehts weiter:
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-242044.html


Anmelden zum Antworten