c - 文件处理时我的二进制搜索树代码中的段错误

标签 c io binary-search-tree

代码没有错误,但没有运行。我在文件处理附近应用了各种打印语句。问题似乎就在那里。有人可以看看他们是否发现了问题吗?

我的输入文件包含以下格式的数据:

Insert "tab>" "name" "tab""IDNo" "tab" "Department""newline"  
Delete "tab""IDNO""newline"  
Find"tab"IDNO"newline"

代码:

/*bst.h*/

typedef struct{
    unsigned int id;
    char name[20];
    char dep[10];
    }studRec;

struct bst;
typedef struct bst binTree;
typedef struct binTree *BST;
struct binTree{
    studRec sRec;
    BST left;
    BST right;
    };

/* bstMain.c*/

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

int main(){
    int s;
    int key,i;
    FILE *f;
    char a[4][20];
    f=fopen("input.txt","r");
    if(f==NULL)
     printf("error");
    else
            printf("no error");
    char ch=getc(f);

    studRec rec;
    BST bt=createEmptyBST();



    do{
            for(i=0;ch!='\n';i++)
                    fscanf(f,"%s",a[i]);

            if(a[0]=="Insert")
                    s=1;
            else if(a[0]=="Delete")
                    {s=2;
                     key=atoi(a[1]);}

            else if(a[0]=="Find"){
                    s=3;
                    key=atoi(a[1]);}
            printf("To print the list, press 4\n To exit,press 5.\n");
            scanf("%d",&s);



    switch(s){
            case 1:

            strcpy(rec.name,a[1]);
            rec.id=atoi(a[2]);
            strcpy(rec.dep,a[3]);
            bt=insertInBST(bt,rec);
            break;

            case 2:

            bt=deleteFromBST(bt,key);
            break;

            case 3:
            rec=findInBST(bt,key);

            case 4:

            inorderTraversal(bt);
            break;

            case 5:

            printf("\nTerminating!!!\n");
            break;

            default:
            printf("\nInvalid Option!! \n");
            break;}
            ch=getc(f);

            }while(ch!=EOF||s==5);
            fclose(f);

}

/*bstOps.c*/

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

BST createEmptyBST(){
    BST root;
    root=(BST)malloc(sizeof(BST));
//      root->sRec=(studRec *)malloc(sizeof(studRec));
    root->sRec.id=0;
    strcpy(root->sRec.name,"/");
    strcpy(root->sRec.dep,"/");
    root->left=NULL;
    root->right=NULL;
    //root=NULL;
    return root;
    }

BST insertInBST(BST bt,studRec rec){

    BST bt1=createEmptyBST();
    bt1=bt;

    while(1){
    /*      if(bt==NULL){
                    bt->sRec=rec;
                    bt->left=NULL;
                    bt->right=NULL;
                    break;}
*/
            if(bt->sRec.id==rec.id)
            {
            return bt;
            break;
            }
            else if(rec.id<bt->sRec.id){
                    if(bt->left==NULL){
                    bt->left=createEmptyBST();
                    bt=bt->left;
                    bt->sRec=rec;
                    break;
                    }
                    else
                            bt=bt->left;
                    }
            else{
                    if(bt->right==NULL){
                    bt->right=createEmptyBST();
                    bt=bt->right;
                    bt->sRec=rec;
                    break;
                    }
                    else
                            bt=bt->right;
            }

    }
    printf("inserted\n");
    return bt1;
    }


void inorderTraversal(BST bt){
    if(bt!=NULL){
            inorderTraversal(bt->left);
            if(bt->sRec.id!=0)
            printf("\t Id:%d\n Name:%s\n Deparment:%s\n",bt->sRec.id,bt->sRec.name,bt->sRec.dep);
            inorderTraversal(bt->right);
            }
    }

studRec findInBST(BST bt,int id){
    BST temp=createEmptyBST();
    if(bt==NULL||bt->sRec.id==0)
            return temp->sRec;
    if(id>bt->sRec.id)
            return findInBST(bt->right,id);
    else if(id<bt->sRec.id)
            return findInBST(bt->left,id);
    else
            return bt->sRec;



}

BST deleteFromBST(BST bt,int id){
    BST q;
    if(bt==NULL||bt->sRec.id==0){
            printf("\nElement not found\n");
            }


    else if(id>bt->sRec.id)
            bt->right=deleteFromBST(bt->right,id);
    else{
            if(bt->right && bt->left){
                    q=FindMin(bt->right);
                    bt->sRec=q->sRec;
                    bt->right=deleteFromBST(bt->right,q->sRec.id);
                    }
            else{
                    q=bt;
                    if(bt->left==NULL)
                            bt=bt->right;
                    else if(bt->right==NULL)
                            bt=bt->left;
                    free(q);
                    }
            }
            return bt;
    }

    BST FindMin(BST bt){
    if(bt==NULL||bt->sRec.id==0){
            return NULL;
            }
    if(bt->left)
            return FindMin(bt->left);
    else
            return bt;
    }
 int getHeight(BST bt){
    int h,lh,rh;
    h=lh=rh-0;
    if(bt->left!=NULL)
            lh=(1+getHeight(bt->left));
    else if(bt->right!=NULL)
            rh=(1+getHeight(bt->right));
    h=lh>rh?lh:rh;
    return(h);
    }

最佳答案

崩溃是由不变循环引起的:

for(i=0;ch!='\n';i++)
    fscanf(f,"%s",a[i]);

停止条件永远不会为真,您最终会覆盖数组 a,这将导致段错误。

这是一个修复建议。你需要根据你的需要更新它

int getHeight(BST bt) {
    int h, lh, rh;
    h = lh = rh = 0;
    if (bt->left != NULL )
        lh = (1 + getHeight(bt->left));
    else if (bt->right != NULL )
        rh = (1 + getHeight(bt->right));
    h = lh > rh ? lh : rh;
    return (h);
}

int main(int argc, char *argv[]) {
    int s;
    int key = 0, i;
    FILE *f;
    char line[200];
    char options[5][200];
    f = fopen(argv[1], "r");

    if (f == NULL ) {
        printf("error");
        return -1;
    }

    printf("no error");

    char ch = fgetc(f);
    studRec rec;
    BST bt = createEmptyBST();

    do {

        for (i = 0; ch != '\n' && ch != EOF; i++) {
            line[i] = ch;
            ch = fgetc(f);
        }

        if (EOF == ch) {
            printf("To print the list, press 4\n To exit,press 5.\n");
            scanf("%d", &s);
        }

        if (!strncmp(line, "Insert", strlen("Insert"))) {
            s = 1;
            // TODO parse the line string to get your options
            sprintf(line, "Insert %s %s %s", options[0], options[1], options[2]);
        } else if (!strncmp(line, "Delete", strlen("Delete"))) {
            s = 2;
            key = atoi(line + strlen("Delete") + 1);
        } else if (!strncmp(line, "Find", strlen("Find"))) {
            s = 3;
            key = atoi(line + strlen("Find") + 1);
        }

        switch (s) {
        case 1:

            strcpy(rec.name, options[0]);
            rec.id = atoi(options[1]);
            strcpy(rec.dep, options[2]);
            bt = insertInBST(bt, rec);
            break;

        case 2:
            bt = deleteFromBST(bt, key);
            break;

        case 3:
            rec = findInBST(bt, key);
            break;

        case 4:

            inorderTraversal(bt);
            break;

        case 5:

            printf("\nTerminating!!!\n");
            ch = EOF; // to  break the do {} while() loop
            break;

        default:
            printf("\nInvalid Option!! \n");
            break;
        }

    } while (ch != EOF || s == 5);
    fclose(f);
    return 0;
}

关于c - 文件处理时我的二进制搜索树代码中的段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15848702/

相关文章:

performance - golang 中的磁盘写入性能

c - #including 标准库是如何工作的?

c++ - 如何获取集合中某个位置的整数?

algorithm - BST 中的第二个最大值

c++ - 这里真的需要 sleep() 吗?

c - C 中的动态数组函数 - 设置容量并创建更大的数组

c - int 变量在语句结果中声明为 double 后如何变化?

c - 条件运算符中的 "error: lvalue required as left operand of assignment"

java - 编写仅读写一列的文本

java - 如何修复二叉树实现的 StackOverflow 错误?