Du må være registrert og logget inn for å kunne legge ut innlegg på freak.no
X
LOGG INN
... eller du kan registrere deg nå
Dette nettstedet er avhengig av annonseinntekter for å holde driften og videre utvikling igang. Vi liker ikke reklame heller, men alternativene er ikke mange. Vær snill å vurder å slå av annonseblokkering, eller å abonnere på en reklamefri utgave av nettstedet.
  2 728
Hei!


driver å jobber med et program i C som leser ifra en fil og lagrer disse dataene i et binær-tre, men i loopen hvor jeg leser fra fil og skal putte inn i treet skjer det noe galt da bare den siste linja som blir lest skrives til treet.

output når jeg kjører programmet ser slik ut...

Kode



1. Get Data From File

2. Delete

3. Search

4. Display

6. Exit

Enter Your Choice : 1

***** Get data from file *****

to

fire

seks

Õtte

ti

1. Get Data From File

2. Delete

3. Search

4. Display

6. Exit

Enter Your Choice : 4



1. Preorder

2. Inorder

3. Postorder

4. Non Recursion

5. Exit

Enter Your Choice : 1

ti

Press Any Key To Continue......

1. Preorder

2. Inorder

3. Postorder

4. Non Recursion

5. Exit

Enter Your Choice :
to,fire,seks,åtte,ti er det som leses fra filen og som så blir printa ut i terminalen.


selve programmet ser slik ut:


Kode

/* 
* File:   main.c
* Author: Nikolai
*
* Created on 22. august 2011, 13:46
*/

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

/*
*
*/
struct node
{
    char famName[20];
    char firstNames[60];
    int ID;
    char address1[30];
    char postCode[12];
    char email[50];
    char boatClass[30];
    char boatName[30];
    struct node *left, *right;
};
void insert(struct node *r, struct node *p)
{
    if ((r->right == NULL) && (strcmp(p->famName, r->famName) > 0))
        r->right = p;
    else if ((r->right != NULL) && (strcmp(p->famName, r->famName) > 0))
        insert(r->right, p);
    if ((r->left == NULL) && (strcmp(p->famName, r->famName) < 0))
        r->left = p;
    else if ((r->left != NULL) && (strcmp(p->famName, r->famName) < 0))
        insert(r->left, p);
}
void tree(struct node *r, int c)
{
    int top, flag;
    struct node *w, *stack[20];
    if (r != NULL)
    {
        if (c != 4)
        {
            if (c == 1)
                printf(" %s ", r->famName);
            tree(r->left, c);
            if (c == 2)
                printf(" %s ", r->famName);
            tree(r->right, c);
            if (c == 3)
                printf(" %s ", r->famName);
        }
    }
    if (c == 4)
    {
        top = 0;
        w = r;
        flag = 0;
        while ((top != - 1) && (w != NULL))
        {
            while ((flag == 0) && (w->left != NULL))
            {
                stack[top] = w;
                top++;
                w = w->left;
            }
            printf(" %s ", w->famName);
            if (w->right != NULL)
            {
                w = w->right;
                flag = 0;
            }
            else
            {
                top--;
                w = stack[top];
                flag = 1;
            }
        }
    }
}
int main()
{
    int choice, c, i, flag;
    char temp = 'N', temp1[15];
    struct node *s, *root, *r, *q;
    root = NULL;
    static const char filename[] = "C:/movieData/file.txt";
    FILE *file = fopen ( filename, "r" );



    do
    {
        printf("\n 1. Get Data From File");
        printf("\n 2. Delete ");
        printf("\n 3. Search ");
        printf("\n 4. Display");
        printf("\n 6. Exit");
        printf("\nEnter Your Choice : ");
        scanf("%d", &choice);
        switch (choice)
        {
        case 1:
        /*HER LIGGER FEILEN EN PLASS*/
            printf("***** Get data from file ***** \n");

            s = malloc(sizeof(struct node));
            s->left = NULL;
            s->right = NULL;

            if ( file != NULL )
            {
                char line [ 128 ]; /* or other suitable maximum line size */
                int fLine  = 1;
                int i = 0;

                while ( fgets ( line, sizeof line, file ) != NULL ) /* read a line */
                {
                    if (fLine)
                    {
                        fLine = 0;
                    }
                    else
                    {

                        if (i % 2 == 0)
                        {
                            strcpy(&s->famName, line);
                            printf("%s",line);
                            //scanf("%s", &s->famName);

                            if (root == NULL)
                            {
                                //printf("root == NULL\n");
                                root = s;
                            }
                            else
                            {
                                //printf("else\n");
                                insert(root, s);
                            }

                            i++;

                        }
                        else
                        {
                            i++;
                        }

                    }
                }
            }

            fclose ( file );

            //else
            //{
            //    perror ( filename ); /* why didn't the file open? */
            //}

        break;
    /*DEN LIGGER NOK IKKE ETTER DETTE*/

        case 2:
            printf("****** Delete Operation *******\n");
            do
            {
                printf("\nEnter Element To Be Deleted : ");
                scanf("%s", temp1);
                s = root;
                i = 0;
                flag = 0;
                do
                {
                    if (strcmp(s->famName, temp1) > 0)
                    {
                        r = s;
                        s = s->left;
                        i = 2;
                    }
                    if (strcmp(s->famName, temp1) == 0)
                    {
                        flag = 1;
                        if (i == 0)
                        {
                            if (root->right != NULL)
                            {
                                q = root->left;
                                root = root->right;
                                insert(root, q);
                            }
                            if (root->right == NULL)
                                root = root->left;
                        }
                        else
                        {
                            if (i == 1)
                            {
                                q = s->left;
                                r->right = s->right;
                                if (s->left != NULL)
                                    insert(r, q);
                            }
                            if (i == 2)
                            {
                                q = s->right;
                                r->left = s->left;
                                if (s->right != NULL)
                                    insert(r, q);
                            }
                        }
                    }
                }
                while (flag == 0 && s != NULL);
                printf("\n Delete Any More[Y/N] : ");
                scanf("%c", &temp);
            }
            while (temp == 'y')
                ;
            break;
        case 3:
            printf("****** Search Operation *******\n");

            printf("\n Enter Name To Be Searched");
            scanf("%s", temp1);
            i = 0;
            s = root;
            while (s != NULL && i == 0)
            {
                if (strcmp(s->firstNames, temp1) < 0)s = s->right;
                if (strcmp(s->firstNames, temp1) > 0)
                    s = s->left;
                if (strcmp(s->firstNames, temp1) == 0)

                    printf("%s", &s->famName);
                i = 1;
            }
            if (i == 0)
                printf("\nElement Not Found\n");
            else
                printf("\nElement Found\n");

            printf("%s", &s->firstNames);
            printf("%s", &s->famName);


            break;
        case 4:
            do
            {
                printf(
                    "\n 1. Preorder\n 2. Inorder \n 3. Postorder \n 4. Non Recursion \n 5. Exit");
                printf("\nEnter Your Choice : ");
                scanf("%d", &c);
                if (root == NULL)
                    printf("Tree Not Started Yet");
                else
                    tree(root, c);
                printf("\n Press Any Key To Continue......");
                int getchar(void);
            }
            while (c != 5);
            break;
        case 5:
            printf("***** Enter full info ***** ");

            s = malloc(sizeof(struct node));
            s->left = NULL;
            s->right = NULL;
            printf("\nEnter famName: ");
            scanf("%s", &s->famName);
            //printf("\nEnter firstNames: ");
            //scanf("%s", &s->firstNames);
            //printf("\nEnter Addres line 1: ");
            //scanf("%s", &s->address1);
            if (root == NULL)
                root = s;
            else
                insert(root, s);


            break;

        }
    }
    while (choice != 6);
    return(0);
}
Programmet kjøres i windows og er kompilert for windows med GCC fra mingw pakken.

regner med feilen ligger i rekkefølgen jeg gjør ting i loopen men har nådd et stadie hvor jeg er totalt kodeblind
Tips: Prøv å kjøre gjennom med en (gjerne grafisk) debugger så ser du hvilke verdier de forskjellige variablene får underveis.
Jeg skrev om insert funksjonen din. Den så rotete ut og her er hvertfall en litt "finere" kode. Jeg la inn en liten kommentar på toppen for å beskrive funksjonen. Dette så ut som en ukesoppgave av noe slag så det er lett å droppe slikt, men hvis du vil bli flink til å kode så er slike detaljer absolutt viktige. Jeg brukte strcmp, men bare fordi du selv brukte den. Ellers bør du aldri bruke den eller lignende funksjoner hvor du ikke presisierer maks antall tegn å kopiere eller sammenligne med(Tenk strcpy, strcmp etc).

Kode

/*
    Inserts a new node into the binary tree.
    If new->famNam exists in the binary tree, it is not added again.
*/
void insert(struct node *n, struct node *new)
{
    if (strcmp(new->famName, n->famName) > 0) { ; Aldri bruk strcmp! Alltid, alltid strncmp.
        if (n->right == NULL)
            n->right = new;
        else
            insert(n->right, new);
    }
    else if (strcmp(new->famName, n->famName) < 0) { ; Aldri bruk strcmp! Alltid, alltid strncmp.
        if (n->left == NULL)
            n->left = new;
        else
            insert(n->left, new);
    }
}
Når det kommer til navn bør du unngå f.eks. "r" istedet for "root". I insert kalte jeg den ene "n", for node, men lot den andre være "new". Det gjør ting veldig mye lettere å lese.

Du sjekker ikke om funksjoner feiler. Fopen er desidert en funksjon som du bør sjekke om feiler.

Kode

FILE *file = fopen ( filename, "r" );

if (file == NULL) {
    perror("fopen");
    exit(1);
}
En annen som er viktig å sjekke er malloc. Den kan også feile så du bør sjekke om den gjør det. Ser at du sjekker file lengere ned, men det er noe du bør gjøre med en gang. Hvis fopen feiler er resten av koden(do-while løkka) meningsløs.

Ikke bruk fclose midt i løkka. Kan godt tenke seg at det er selve feilen. Bra bruk av fclose, men kjør den først etter løkka. Ser litt ut som du egentlig vil legge inn linjen "file = fopen(filename, "r")" før du sjekker om "file != NULL" i case 1.

Prøv å lag en egen delete funksjon som går rekursivt gjennom binærtree for å finne noden du skal slette. Vil se mye bedre ut og er sikkert en fin øvelse.