C语言头结点后继结点为空

问题遇到的现象和发生背景

C语言头结点后继结点为空,但链表不为空,导致无法输出链表,删除指定键值函数运行到了就会闪退。

用代码块功能插入代码,请勿粘贴截图

#include
#include
#include

typedef char elemtype;
typedef struct node
{
elemtype data;
struct node * next;
}Lnode , *L;

//初始化链表
void InitialList(Lnode *h)
{

h = (Lnode *)malloc(sizeof(Lnode));
if (h == NULL) 
{
    printf("函数执行,内存分配失败,初始化单链表失败");
}
else
{

    (h)->next = NULL;
    printf("函数执行,带头结点的单链表初始化完成\n");
}

}
//创建链表
Lnode *creat()
{
FILE * fp;
Lnode *h,*p,*t;
elemtype ch;
h=(Lnode *)malloc(sizeof(Lnode));
memset(h, 0, sizeof(Lnode));
h->next=NULL;
t=h;
if((fp=fopen("1.txt","r"))==NULL)
{
printf("false\n");
exit(0);
}
while(!feof(fp))
{
fscanf(fp,"%c",&ch);
p=(Lnode *)malloc(sizeof(Lnode));
p->data=ch;
p->next=NULL;
t->next=p;
t=p;
}
return h;
}
//测表的长度
int length(Lnode *h)
{
Lnode *p;
int i=0;
p=h->next;
while(p)
{
i++;
p=p->next;
}
return i;
}
//输出链表
void Print(Lnode *h)
{
Lnode *p;
p=(Lnode *)malloc(sizeof(Lnode));
p = h->next;
while (p != NULL)
{
printf("%d ",p->data);
p = p->next;
}
printf("\输出函数已执行\n");
}

//取第i个元素键值
Lnode *get(Lnode *h,int i)
{
int j;
Lnode *p;
p=h->next;
j=1;
while(p&&j
{
p=p->next;
j++;
}
if(i==j)
return p;
else
return NULL;
}
//删除指定位置的元素
void deleAdr(Lnode *h,int i)
{
Lnode *p,*q;
int j;
p=h;
j=0;
while(p&&j!=i-1)
{
p=p->next;
j++;
}/寻找第i号结点/if(p->next!=NULL)
{
q=p->next;//q为p的直接后继
p->next= q->next;
free(q);
}
}

//删除指定键值元素
void deleKey(Lnode *h,elemtype x)
{
Lnode *p,*q;
int j;
p=h;
j=0;
while(p->data!=x)
{
p=p->next;
j++;
}if(p->data=x)
{
q=(Lnode *)malloc(sizeof(Lnode));
p=q->next;
q->next=p->next;
free(p);
}
}
//向表的头部添加键值为Key的元素
int insertHead(Lnode *h,elemtype x)
{

Lnode *p,*s;
p=(Lnode *)malloc(sizeof(Lnode));

if(p)
{
    h=p->next;    
    s=(Lnode *)malloc(sizeof(Lnode));
    s->data=x;
    s->next=p->next;
    p->next=s;
    return (1);
}
else
{
    return(0);
}

}

//向表的尾部添加键值为Key的元素
void insertEnd(Lnode *h,elemtype x)
{
Lnode *p,*s;
int j;
p=h;
j=0;
int i=length(h);
while(p&&j
{
p=p->next;
j++;
}
if(p)
{
s=(Lnode *)malloc(sizeof(Lnode));
s->data=x;
s->next=p->next;
p->next=s;
}
}
//向表中指定位置添加键值为Key的元素
int insert(Lnode *h,int i,elemtype x)
{
Lnode *p,*s;
int j;
p=h;
j=0;
while(p&&j
{
p=p->next;
j++;
}
if(p)
{
s=(Lnode *)malloc(sizeof(Lnode));
s->data=x;
s->next=p->next;
p->next=s;
return(1);
}
else
return 0;
}
//查询键值为Key元素所在位置
Lnode *search(Lnode *h,elemtype x)
{
Lnode *p;
p=h->next;
while(p&&p->data!=x)
{
p=p->next;
}
return(p);
}

void main()
{
Lnode *h;
h=(Lnode *)malloc(sizeof(Lnode));
InitialList(h);
creat();
if(h->next=NULL)
{
printf("链表初始化失败\n");
exit(0);
}
else
{
Print(h);
int i;
printf("请输入您查找元素的位置:\n");scanf("%d",&i);
get(h,i);
printf("%d\n",get(h,i));//查找i位置上的元素

    printf("请输入您希望删除的元素位置:\n");
    int c;
    scanf("%d",&c);
    deleAdr(h,c);
    //删除Key位置的元素

    printf("请输入您希望删除的元素的值\n");
    char d;
    scanf("%c",&d);
    deleKey(h,d);
    //删除Key键值元素

    printf("请输入插入值\n");
    char e;
    scanf("%c",&e);
    insertHead(h,e);
    //在表头插入键值为Key的元素

    printf("请输入插入值\n");
    char f;
    scanf("%c",&f);
    insertEnd(h,f);
    //在表尾插入键值为Key的元素
    printf("请输入插入值\n");
    char g;
    scanf("%c",&g);
    insert(h, i,g);
    //在表中任意位置插入键值为Key的元素
    printf("请输入要搜索的元素\n");
    char n;
    scanf("%c",&n);
    search(h,n);
    //搜索键值为Key的元素
    Print(h);
}

}

运行结果及报错内容

img

我的解答思路和尝试过的方法

加了一个初始化函数,无效。

我想要达到的结果

完整输出链表文件内容:apple

改了一下,可以输出文件内容了

img

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

typedef char elemtype;
typedef struct node
{
    elemtype data;
    struct node * next;
} Lnode , *L;

//初始化链表
Lnode *InitialList(Lnode *h)
{

    h = (Lnode *)malloc(sizeof(Lnode));
    if (h == NULL)
    {
        printf("函数执行,内存分配失败,初始化单链表失败");
    }
    else
    {

        (h)->next = NULL;
        return h;
        printf("函数执行,带头结点的单链表初始化完成\n");
    }
    
}
//创建链表
Lnode *creat()
{
    FILE * fp;
    elemtype ch;
    Lnode *L = InitialList(L), *r, *n;//分别定义头指针、尾指针、新指针
    r = L;//尾指针初始化为头指针

    fp=fopen("1.txt","r");
    if(fp==NULL)
    {
        printf("false\n");
        exit(0);
    }
    while(fscanf(fp,"%c",&ch)==1)
    {
        n = (Lnode *) malloc(sizeof(Lnode));//申请空间
        n->data = ch;
        n->next = NULL;//新指针指针域置空
        r->next = n;//将新指针链入单链表末尾
        r = r->next;//尾指针往后移
    }
    return L;
}
//测表的长度
int length(Lnode *h)
{
    Lnode *p;
    int i=0;
    p=h->next;
    while(p)
    {
        i++;
        p=p->next;
    }
    return i;
}
//输出链表
void Print(Lnode *h)
{
    Lnode *p;
    p=(Lnode *)malloc(sizeof(Lnode));
    p = h->next;
    while (p != NULL)
    {
        printf("%c ",p->data);
        p = p->next;
    }
    printf("输出函数已执行\n");
}

//取第i个元素键值
char get(Lnode *h,int i)
{
    int j;
    Lnode *p;
    p=h->next;
    j=1;
    while(p&&j<i)
    {
        p=p->next;
        j++;
    }
        return p->data;
}
int deleAdr(Lnode *L, int pos)
{
    if(pos < 1 || pos > length(L)) return 0;//删除位置错误
    Lnode *r = L, *d;
    while(--pos > 0)
    {
        r = r->next;//将尾指针移动到删除位置
    }
    d = r->next;//删除元素节点
    //*e = d->data;//保存删除元素值
    r->next = d->next;//将尾指针跳过删除节点链入下一个节点
    free(d);//释放删除节点
    return 1;
}

/*
void deleAdr(Lnode *h,int i)
{
    Lnode *p,*q;
    int j;
    p=h;
    j=0;
    while(p&&j!=i-1)
    {
        p=p->next;
        j++;
    }//寻找第i号结点/if(p->next!=NULL)
    {
        q=p->next;//q为p的直接后继
        p->next= q->next;
        free(q);
    }
}*/

//删除指定键值元素
void deleKey(Lnode *h,elemtype x)
{
    Lnode *p,*q;
    int j;
    p=h;
    j=0;
    while(p->data!=x)
    {
        p=p->next;
        j++;
    }
    if(p->data==x)
    {
        q=(Lnode *)malloc(sizeof(Lnode));
        p=q->next;
        q->next=p->next;
        free(p);
    }
}
//向表的头部添加键值为Key的元素
int insertHead(Lnode *h,elemtype x)
{

    Lnode *p,*s;
    p=(Lnode *)malloc(sizeof(Lnode));

    if(p)
    {
        h=p->next;
        s=(Lnode *)malloc(sizeof(Lnode));
        s->data=x;
        s->next=p->next;
        p->next=s;
        return (1);
    }
    else
    {
        return(0);
    }
}

//向表的尾部添加键值为Key的元素
void insertEnd(Lnode *h,elemtype x)
{
    Lnode *p,*s;
    int j;
    p=h;
    j=0;
    int i=length(h);
    while(p&&j<i)
    {
        p=p->next;
        j++;
    }
    if(p)
    {
        s=(Lnode *)malloc(sizeof(Lnode));
        s->data=x;
        s->next=p->next;
        p->next=s;
    }
}
//向表中指定位置添加键值为Key的元素
int insert(Lnode *h,int i,elemtype x)
{
    Lnode *p,*s;
    int j;
    p=h;
    j=0;
    while(p&&j<i-1)
    {
        p=p->next;
        j++;
    }
    if(p)
    {
        s=(Lnode *)malloc(sizeof(Lnode));
        s->data=x;
        s->next=p->next;
        p->next=s;
        return(1);
    }
    else
        return 0;
}
//查询键值为Key元素所在位置
Lnode *search(Lnode *h,elemtype x)
{
    Lnode *p;
    p=h->next;
    while(p&&p->data!=x)
    {
        p=p->next;
    }
    return(p);
}

int main()
{
    Lnode *h;
    h=(Lnode *)malloc(sizeof(Lnode));
    //InitialList(h);
    h=creat();
    if(h->next==NULL)
    {
        printf("链表初始化失败\n");
        exit(0);
    }
    else
    {
        Print(h);
        int i;
        printf("请输入您查找元素的位置:\n");
        scanf("%d",&i);
        //get(h,i);
        printf("%c\n",get(h,i));//查找i位置上的元素

        printf("请输入您希望删除的元素位置:\n");
        int c;
        scanf("%d",&c);
        deleAdr(h,c);
        Print(h);
        //删除Key位置的元素

        fflush(stdin);
        printf("请输入您希望删除的元素的值\n");
        char d;
        scanf("%c",&d);
        deleKey(h,d);
        Print(h);
        //删除Key键值元素

        printf("请输入插入值\n");
        char e;
        scanf("%c",&e);
        insertHead(h,e);
        Print(h);
        //在表头插入键值为Key的元素

        printf("请输入插入值\n");
        char f;
        scanf("%c",&f);
        insertEnd(h,f);
        Print(h);
        //在表尾插入键值为Key的元素
        printf("请输入插入值\n");
        char g;
        scanf("%c",&g);
        insert(h, i,g);
        //在表中任意位置插入键值为Key的元素
        printf("请输入要搜索的元素\n");
        char n;
        scanf("%c",&n);
        search(h,n);
        //搜索键值为Key的元素
        Print(h);
    }
}

main函数里面的 InitialList(h) 可以不要了,在 creat 里面初始化了头。
还有 if(h->next=NULL) 错了,比较是两个等号 h->next == NULL,一个等号直接把 next 给赋值为 NULL 了。另外,你的程序中还有 deleKey 函数里面的 if(p->data=x) 也是一样的问题,p->data == x。

img

img

img

你这是要将文档里的每个字符串成一条链表吗?
如果是的话,create函数可以读一个字符创建一个节点并赋值,然后打印出来就有了。可以打印多点信息,观察每一步是不是预期的结果。
初始化InitialList这个函数,你写的是值传递参数,如果想让它起修改h的作用,要改成传指针的指针

提供参考链接【c语言链表头结点为空,一个关于C语言链表头结点的问题】,期望对你有所帮助:https://blog.csdn.net/weixin_35322457/article/details/117164735