Zeiger auf Structur für Speicherreservierung (malloc)



  • sry, ich meinte MS Visual C++



  • struct kartei *erster = (struct kartei *) malloc (sizeof(struct kartei));
    

    oder gleich C++, also new verwenden.



  • feigling schrieb:

    oder gleich C++, also new verwenden.

    besser nicht, damit handelt man sich nur noch mehr stress ein.
    einfach die source code datei in .c umbenennen...
    🙂



  • Endlich......
    es funktioniert.

    Vielen vielen Dank



  • Hi
    Hab noch immer ein paar probleme. und zwar findet er jetzt das ende meiner liste nicht, also dieses NULL.
    woran liegt das?????

    temp=erster;
    while (temp->next!=NULL)
    {

    printf ("kontrolle");
    fprintf(fp1,"%s \t %d \t %s \t %d.%d.%d\n ",(*temp).name,(*temp).semester,(*temp).status,(*temp).d.tag,(*temp).d.monat,(*temp).d.jahr);
    temp=temp->next;
    }



  • kann keiner einen fehler entdecken? der will nicht mehr aus der schleife raus gehen???



  • steppe durch den code. deine schleifenbedingung ist im a.



  • c.rackwitz schrieb:

    steppe durch den code. deine schleifenbedingung ist im a.

    wie meinst du das?



  • do
    { 
        temp=temp->next;
    
    } while (temp != NULL);
    

    muss klappen, is ja egal wie rum man macht. übrignes crackwitz meint deine schleifenbedingung ist im a-r-s-c-h falls dir das a kopfzerbrechen bereitet hat 😉

    PS: der überischtlichkeit halber verwende doch generell "temp->element" und bitte [cpp] tags.



  • Ja, mit dem a. war mir schon klar, wusste (weiß) nur nicht warum.

    mit dem do while funktioniert leider auch nicht.

    temp ist ein zeiger auf ein element einer liste. warum findet der nicht wenn es das letzte element ist?? oder muss ich das letzte element schon vorher irgendwie bestimmen?



  • Jaepen schrieb:

    wie meinst du das?

    wie meinst du das?



  • c.rackwitz schrieb:

    Jaepen schrieb:

    wie meinst du das?

    wie meinst du das?

    Rekursion ist hier nicht das Thema 😉



  • kann ja wohl nicht angehen, dass hier einer "woran liegt das?????" schreit, sonst kein wort sagt was nicht verstanden wird, und dann auch noch hilfe bekommt!

    und klar gehts hier um rekursion! was ist denn wohl ne verkettete liste?
    im uebrigen ist ein do-while hier an sich falsch. warum?

    temp = erster;
    do... // crasht, wenn erster schon NULL ist, also ne leere liste vor einem liegt
    

    die while() bedingung ist einfach falsch. das ->next muss weg.
    warum macht nicht einfach mal einer nen eintrag in die FAQ "wie debugge ich richtig" und klatscht jedem das um die ohren, der denkt, sich die muehe nicht machen zu muessen?

    *mit-dem-krueckstock-fuchtel*



  • [quote="c.rackwitz"]kann ja wohl nicht angehen, dass hier einer "woran liegt das?????" schreit, sonst kein wort sagt was nicht verstanden wird, und dann auch noch hilfe bekommt!

    Hi
    Tut mir leid, aber ich dachte das wäre nur ein kleiner syntax fehler, den ein erfahrener Prigrammiere direkt sehen würde. Ich bin nämlich leider ein absoluter anfänger.

    Mitlerweile habe ich das Problem über Umwege gelöst. (ich zähle von anfang an immer meine Listen element mit, das ich immer weiß wie viele ich habe)

    Mein Problem ist also folgendes:

    Ich lege eine einfach verkettete liste an, mit einer variablen anzahl von Elementen, die ich aus einer Datei auslese.

    fp1=fopen ("stud.txt", "r");

    if (fp1 == NULL ) { printf ("\nDie Datei konnte nicht zum lesen geöffnet werden!\n");}
    else
    {

    akt=(struct kartei 😉 malloc (sizeof(struct kartei));
    erster=akt;

    while (!feof(fp1))
    {
    j++;
    fscanf(fp1,"%s \t %d \t %s \t %d.%d.%d\n", (*akt).name, &(*akt).semester, &(*akt).status, &(*akt).d.tag, &(*akt).d.monat, &(*akt).d.jahr);
    printf("Student: %s \t %d \t %s \t %d.%d.%d\n", (*akt).name, (*akt).semester, (*akt).status, (*akt).d.tag, (*akt).d.monat, (*akt).d.jahr);

    akt->next=(struct kartei 😉 malloc (sizeof(struct kartei));
    akt=akt->next;

    };

    Dann füge ich elemente zu oder lösche welche.
    Schließlich will ich alle Elemente auch wieder zurück schreiben.

    uebernehmen(int j)
    {
    fp1=fopen ("stud.txt", "w");
    if (fp1 == NULL ) { printf ("\nDie Datei konnte nicht zum schreiben geöffnet werden!\n");}
    else {

    temp=erster;

    while (j)
    {
    printf("z ");
    fprintf(fp1,"%s \t %d \t %s \t %d.%d.%d\n ",(*temp).name,(*temp).semester,(*temp).status,(*temp).d.tag,(*temp).d.monat,(*temp).d.jahr);
    temp=temp->next;
    j--;
    }
    }
    fclose (fp1);
    return(0);

    Mein Problem ist dabei das ich nicht weiß wie ich die Abfrage mache wann beim übernehmen das letzte Element erreicht ist. (Im übrigen habe ich keine Ahnung was das Wort debug auch nur ansatzweise bedeuten soll).

    mfg Jaepen



  • Jaepen schrieb:

    Mein Problem ist dabei das ich nicht weiß wie ich die Abfrage mache wann beim übernehmen das letzte Element erreicht ist. (Im übrigen habe ich keine Ahnung was das Wort debug auch nur ansatzweise bedeuten soll).

    mfg Jaepen

    als "bugs" werden eben fehler im programm bezeichnet. sie können zu programmabstürtzen, systemabstrürtzen und sowas führen. die ursachen sind sehr vielfältig. das vorangestellte "de" ("debuggen") kehrt den ausdruck um, also = das programm von solchen fehlern zu bereinigen.

    aber zum eigentlichen problem: voraussetzung dafür, dass die schleifenbedingung wahr ist, ist natürlich das der next pointer NULL ist. und stimmt: bei der do... while schleife muss natürlich geprüft werden, ob der next pointer der ersten struktur schon NULL ist. aber falsch ist diese lösung mit den schleifen keineswegs! möglicherweise liegt der fehler irgendwo anders im programm. wenn der code nicht zu umfangreich ist dann poste ihn mal bitte komplett.



  • so, das ist der code soweit. Funktioniert soweit auch, nur das mit dem "in datei übernehmen" ist halt irgendwie unsauber, da ich halt die elemente zählen muss. Ich hoffe das ich nicht allzuviel von den Profis kritisiert werde, bin halt noch anfänger 😉

    struct datum {
    int tag;
    int monat;
    int jahr;};

    struct kartei {
    char name [20];
    char status[1];
    int semester;
    datum d;
    kartei *next;
    };

    FILE *fp1;
    struct kartei *temp;
    struct kartei *akt;
    struct kartei *erster;
    struct kartei *vorgaenger;

    uebernehmen(int j)
    {
    fp1=fopen ("stud.txt", "w");
    if (fp1 == NULL ) { printf ("\nDie Datei konnte nicht zum schreiben geöffnet werden!\n");}
    else {

    temp=erster;
    while (j)
    {
    fprintf(fp1,"%s \t %d \t %s \t %d.%d.%d\n ",(*temp).name,(*temp).semester,(*temp).status,(*temp).d.tag,(*temp).d.monat,(*temp).d.jahr);
    temp=temp->next;
    j--;
    }
    }
    fclose (fp1);
    return(0);
    }

    //MAIN***************************************************************************************************************MAIN

    int main(int argc, char **argv) {

    char b; //Befehl einlesen
    int a=0; //Schmiermerker
    int j=0; //zählmerker der karteien
    int k=0; // zähler 2 für blättern

    //Datei auslesen******************

    fp1=fopen ("stud.txt", "r");

    if (fp1 == NULL ) { printf ("\nDie Datei konnte nicht zum lesen geöffnet werden!\n");}
    else
    {

    akt=(struct kartei 😉 malloc (sizeof(struct kartei));
    erster=akt;

    while (!feof(fp1))
    {
    j++;
    fscanf(fp1,"%s \t %d \t %s \t %d.%d.%d\n", (*akt).name, &(*akt).semester, &(*akt).status, &(*akt).d.tag, &(*akt).d.monat, &(*akt).d.jahr);
    printf("Student: %s \t %d \t %s \t %d.%d.%d\n", (*akt).name, (*akt).semester, (*akt).status, (*akt).d.tag, (*akt).d.monat, (*akt).d.jahr);

    akt->next=(struct kartei 😉 malloc (sizeof(struct kartei));
    akt=akt->next;
    };
    }
    fclose (fp1);

    //******************************
    printf ("\n\n\tdruecken sie *z* um den nächsten datensatz anzuzeigen\n");
    printf ("\tdruecken sie *j* um einen neuen Datensatz anzulegen\n");
    printf ("\tdruecken sie *x* um das Programm zu beenden \n");
    printf ("\tdruecken sie *l* um ein Element zu loeschen \n");

    printf ("\n\tMomentan Studierende an der FH:\n\n");
    printf("Student: %s \t %d \t %s \t %d.%d.%d\n\n", (*erster).name, (*erster).semester, (*erster).status, (*erster).d.tag, (*erster).d.monat, (*erster).d.jahr);

    akt=erster;

    do{ //große schleife , abfrage auf j, x, l, oder z
    b=getchar();

    switch (b)
    {

    case 'z': //********************** wenn z wird nächster Datensatz ausgegeben

    vorgaenger=akt;
    akt=akt->next;
    printf("Student: %s \t %d \t %s \t %d.%d.%d\n\n", (*akt).name, (*akt).semester, (*akt).status, (*akt).d.tag, (*akt).d.monat, (*akt).d.jahr);

    break;

    case 'j': //*********************** wenn j wird ein Datensatz eingefügt

    while (b=='j')
    {
    temp=akt->next;
    akt->next=(struct kartei*)malloc(sizeof(struct kartei));
    akt->next->next=temp;
    akt=akt->next;
    j++; //Zählmerker +1 da eine Kartei mehr

    printf ("geben sie einen namen ein\n");
    scanf("%s",((*akt).name));

    printf ("geben sie das Semester ein(1 bis 10)\n");
    scanf("%d",&(*akt).semester);

    printf ("geben sie den Status ein (a oder b)\n");
    scanf("%s",(*akt).status);

    printf ("geben sie das Datum ein (Tag.Monat.Jahr / aa.bb.cccc)\n");
    scanf("%d.%d.%d",&(*akt).d.tag,&(*akt).d.monat,&(*akt).d.jahr);

    temp=akt;

    uebernehmen (j);

    akt=erster;
    b='q';
    printf ("\n\tDatensatz erfolgreich eingefuegt, was moechten sie nun tun?\n");
    }
    break;

    case 'l': //************** element löschen
    temp=akt->next;
    vorgaenger->next=temp;
    delete akt;
    j--; //anzahl der Karteien um eins veringern
    akt=vorgaenger->next;

    uebernehmen (j); //Funktionsaufruf

    printf("\nloschen erfolgreich. Was möchten sie jetzt tun?\n");
    break ;

    } //klammer switch
    } //klammer do while

    while (b!='x'); //wenn x, wird große schleife verlassen, und programm ende

    return 0;
    }



  • Benutzt [cpp]-Tags. Das war keine Bitte.



  • davon abegesehen dass es jetzt immernoch nicht abbrich und man weitere strukturen ausgeben kann nachdem die letzte erreicht ist würde ich folgendes ändern:

    -zu viele globale variablen

    -zu wenige checks z.b. ob überhaupt noch datensätze verfügbar sind

    -jedes element der struktur in eine eigene zeile schreiben und dann per fgets() einlesen (im notfall:ein leerzeichen statt tab dazwischen machen, kann man ja bei der ausgabe ändern)

    -wenn das mit den listen absolut nich klappen will: nimm eine andere bedingung.

    -du musst checken wann das textfile zu ende ist (EOF) und wann ein datensatz zuende ist. du kannst markierungen zwischen die datensätze schreiben die kennzeichnen: "hier fängt eine neuer datensatz an!".

    ich würde den code fast komplett umschreiben und wenn ich noch zeit hab werd ichs auch noch machen 😉



  • Ja, ich weiß das es da noch einiges zu verbessern gäbe. Bin im moment aber mal froh das ich das einfach irgendwie hinbekommen habe. Da ich wie gesagt noch absoluter anfänger bin, hab ich das auch nicht einfach mal so runter programmiert. Da steckt ein haufen arbeit drin ;-). Drauche das Programm für meinen Laborschein, und hab im mom auch nicht so viel zeit für mich noch stunden lang damit zu beschäftigen.

    gruß

    P.S: es wäre super wenn mir jemand sagen könnte was cpp tags sin? (Vermutung: die weißen Fenster mit dem Quellcode drin, aber wie einfügen?)



  • jaepen schrieb:

    P.S: es wäre super wenn mir jemand sagen könnte was cpp tags sin? (Vermutung: die weißen Fenster mit dem Quellcode drin, aber wie einfügen?)

    in der editbox beim posting abschicken markierst du einfach den quelltext und dann click auf den button darunter mit der beschriftung 'c/c++'
    🙂


Anmelden zum Antworten