火车退票功能有点搞不懂

1.订票代码和f1()函数一起用没问题。订票和退票一起用有问题,退票代码改了好几次,现在运行直接结束了。
2.退票功能要求是:乘客输入车次和身份证号码,在该车次对应的链表中查找该乘客,若找到,询问乘客退票数量,若退票数小订票数,则只需修改结点的订票数;若退票数等于订票数,则将该乘客对应的结点删除,然后修改该车次的余票数;若没找到,则应提示“未找到相应信息”,要求乘客重新输入车次和身份证号码,再进行查找,如果仍未找到,则输出提示信息“输入信息错误,退票失败!”。
3.函数tp1()我是用来解决没找到乘客之后再次输入信息来查找;变量n用来看line.head是不是line.head链表的头结点,因为删除头结点和非头结点不一样;变量flag用来看找没找到乘客信息;指针k指向line的头,k.head指向line.head的头,指针j和j1分别指向line.head和line.head.next,用来删除非头结点的结点。
4.我逻辑有点混乱了,请教各位

#include
#include 
#include
struct node
{  
   char name[12];         //乘客姓名
   char IDcard[20];        //乘客身份证号码
   int TicketNum;         //订票数
   float FareSum;         //总票价
   struct node *next;      //指针成员
}*p3,*p4;
struct Dtime
{  
   short year;
   short month;
   short day;
   short hour;
   short minute;
};
struct train
{   
   char terminal[20];          //终点站
   char sequence[20];         //车次
   struct Dtime StartTime;     //发车时间
   float fare;                //票价
   int SpareTicketNum;       //余票数
   struct node *head;         //指针成员,指向该线路第一个订票乘客
   struct train *next;
}*line,*p1,*p2;
void train_information()    //输入列车信息 
{
    printf("|-------------------------列车信息存入-------------------------|\n");
    printf("终点站     车次           发车时间          票价        余票数\n");
    int n=0;
    line=NULL;
    while(n<5)
    { 
        p1=(struct train *)malloc(sizeof(struct train));
        scanf("%s %s %d.%d.%d.%d:%d%f%d",p1->terminal,p1->sequence,&p1->StartTime.year,&p1->StartTime.month,&p1->StartTime.day,&p1->StartTime.hour,&p1->StartTime.minute,&p1->fare,&p1->SpareTicketNum);
        p1->next=NULL;
        p1->head=NULL;
        if(line==NULL)
           line=p1;
        else 
           p2->next=p1;
        p2=p1;
        n++;
    }
}
void dp()                                      //订票功能 
{
    printf("|--------------------------火车票预订--------------------------|\n");
    train *j;
    j=line;
    char checi[20];
    int  num;
    printf("车次:");
       scanf("%s",checi);
    printf("\n"); 
    printf("订票数:");
       scanf("%d",&num);
    printf("\n"); 
    while(line)
    {
        if(strcmp(line->sequence,checi)==0)
        {
            if(line->SpareTicketNum>=num)
              {
                  printf("|-----个人信息登记-----|\n");
                  line->SpareTicketNum-=num;            //余票数减少 
                  p3=(struct node *)malloc(sizeof(struct node));
                  printf("姓名:");
                  scanf("%s",p3->name);
                      printf("\n");  
                printf("身份证号码:");
                  scanf("%s",p3->IDcard);
                      printf("\n"); 
                printf("总票价:%.2f\n",num*line->fare);
                p3->TicketNum=num;
                p3->FareSum=num*line->fare;
                p3->next=NULL;
                if(line->head==NULL)
                  line->head=p3;
                else
                    p4->next=p3;
                p4=p3;
                line=j;
                break;
              }
            else
              {
                      printf("\n"); 
                printf("余票数不足,订票失败!\n");
                line=j;
                break;
              }
        }
        line=line->next;
    }
}
void tp1(char cc[20],char sfz[20])                        //退票功能的内部函数 
{
    int tpnum,flag=0;
    train *k,*j;
    k=j=line;
    k->head=j->head; 
    while(k)
    {
        while(k->head)
        {
            if(strcmp(k->head->IDcard,sfz)==0)
            {
                flag=1;
               printf("退票数量:");
               scanf("%d",&tpnum);
                   printf("\n"); 
               if(tpnumhead->TicketNum)
               {
                   k->head->TicketNum-=tpnum;
                   k->SpareTicketNum+=tpnum;
                   k->head->FareSum-=tpnum*k->fare;
                   printf("退票成功\n");
                   k->head=line->head; 
                   break;
               }
               if(tpnum==k->head->TicketNum)
               { 
                    k->SpareTicketNum+=tpnum;                             //删除结点 
                    if(k->head==line->head)
                    {
                        
                        line->head=k->head->next;
                        free(k->head);
                    }
                    else 
                    {
                        j->head=k->head->next;
                        free(k->head); 
                    }                                                            
                //    k->head=j->head=line->head;
                    j->head=line->head;
                    printf("退票成功\n");   
                    break;
                }
            }
            j->head=k->head;
           k->head=j->head->next;
        }
        k=k->next;
        if(flag==1)
        {
            k->head=line->head;
            break;
        }
    }
    if(flag==0)
        printf("输入信息错误,退票失败!\n");            
}
void tp()                                             //退票功能
{
    printf("|---------------------------退票功能---------------------------|\n");
    train *k,*j,*j1;
    char cc[20],sfz[20],cc1[20],sfz1[20];
    int tpnum,flag=0,n=0;
    k=line;
    k->head=line->head;
    printf("车次:"); 
    scanf("%s",cc);
    printf("身份证号码:");
    scanf("%s",sfz);
    while(line)
    { 
        j=j1=line;
        if(strcmp(line->sequence,cc)==0)
        {
            while(line->head)
            {
                
                j->head=line->head;
                j1->head=j->head->next;
                if(strcmp(line->head->IDcard,sfz)==0)
                {
                    flag=1;
                     printf("退票数量:");
                    scanf("%d",&tpnum);
                    printf("\n");
                    if(tpnumhead->TicketNum)
                    {
                          line->head->TicketNum-=tpnum;
                          line->SpareTicketNum+=tpnum;
                          line->head->FareSum-=tpnum*k->fare;
                          printf("退票成功\n");
                         // line->head=line->head;
                          break;
                     }
                    if(tpnum==line->head->TicketNum)
                    {
                        line->SpareTicketNum+=tpnum;                             //删除结点 
                        if(n==0)
                        {
                            line->head=line->head->next;
                            free(j->head);
                        }
                        else 
                        {
                            j->head->next=j1->head->next;
                            free(j1);
                        }                                                            
                        printf("退票成功\n");
                        break;
                    }
                }
                line->head=line->head->next;
                n++;
            }
            if(flag==0)
            {
                printf("\n");
                printf("未找到相应信息\n");
                printf("车次:"); 
                scanf("%s",cc1);
                printf("身份证号码:");
                scanf("%s",sfz1);
                //tp1(cc1,sfz1);
                line->head=k->head;
                line=k;
                break;
            }
            if(flag==1)
            {
                line->head=k->head;
                line=k;
                break;
            }
        }
        line=line->next; 
    }
} 
void  f1()                  //输入车次,输出该车次的全部订票信息
{
    printf("|--------------输入车次,输出该车次的全部订票信息--------------|\n");
    train *f;
    char checi[20];
    f=line;
    printf("车次:"); 
    scanf("%s",checi);
    while(f)
    {
        if(strcmp(f->sequence,checi)==0)
        {
            while(f->head)
            {
                printf("姓名   身份证号码    订票数    总票价\n");
                printf("%s        %s          %d        %.2f\n",f->head->name,f->head->IDcard,f->head->TicketNum,f->head->FareSum);
                f->head=f->head->next;
            }
            break;
        }
        f=f->next;
    }
}

修改完善如下,功能见注释,供参考:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node
{
    char name[12];   //乘客姓名
    char IDcard[20]; //乘客身份证号码
    int TicketNum;   //订票数
    float FareSum;   //总票价
    struct node* next;//指针成员
};                
struct Dtime
{
    short year;
    short month;
    short day;
    short hour;
    short minute;
};
struct train
{
    char terminal[20];  //终点站
    char sequence[20];  //车次
    struct Dtime StartTime; //发车时间
    float fare;             //票价
    int  SpareTicketNum;    //余票数
    struct node* head;      //指针成员,指向该线路第一个订票乘客
    struct train* next;
}*line = NULL;

void input_train()
{
    printf("|-----------------列车信息存入------------------|\n");
    printf("终点站  车次        发车时间       票价   余票数\n");
    while (1) {
        struct train* newtrain = (struct train*)malloc(sizeof(struct train));
        newtrain->next = NULL;
        newtrain->head = NULL;
        scanf("%s", newtrain->terminal);
        if (strcmp(newtrain->terminal, "end") == 0) //终点站输入“end”结束车辆信息录入
        {
            free(newtrain);
            break;
        }
        scanf("%s %hd %hd %hd %hd %hd %f %d", newtrain->sequence, &newtrain->StartTime.year, 
            &newtrain->StartTime.month,&newtrain->StartTime.day, &newtrain->StartTime.hour, 
            &newtrain->StartTime.minute, &newtrain->fare, &newtrain->SpareTicketNum);
        if (!line)
            line = newtrain;
        else {
            struct train* p = line;
            while (p->next)
                p = p->next;
            p->next = newtrain;
        }
    }
}

struct train* find_TrainNo() //查找车次函数
{
    char TrainNo[20];
    struct train* pt = line;
    printf("车次:");
    scanf("%s", TrainNo);
    while (pt) {
        if (strcmp(pt->sequence, TrainNo) == 0)
            break;
        pt = pt->next;
    }
    return pt;
}

struct node* find_Traveller(struct train* pline) //查找乘客函数
{
    struct node* pt = pline->head;
    char IDcard[20];
    printf("乘客身份证号:");
    scanf("%s", IDcard);
    while (pt) {
        if (strcmp(pt->IDcard, IDcard) == 0)
            break;
        pt = pt->next;
    }
    return  pt;
}
void dp()  //订票功能 
{
    printf("|----------------火车票预订---------------|\n");
    int num;
    struct train* j = find_TrainNo();
    if (j) {
        printf("订票数:");
        scanf("%d", &num);
        if (j->SpareTicketNum >= num)
        {
            printf("|-----个人信息登记-----|\n");
            j->SpareTicketNum -= num;
            struct node* newpassenger = (struct node*)malloc(sizeof(struct node));
            printf("姓名:");
            scanf("%s", newpassenger->name);
            printf("身份证号:");
            scanf("%s", newpassenger->IDcard);
            printf("总票价:%.2f\n", num * j->fare);
            newpassenger->TicketNum = num;
            newpassenger->FareSum = num * j->fare;
            newpassenger->next = NULL;
            if (!j->head)
                j->head = newpassenger;
            else {
                struct node* pt = j->head;
                while (pt->next)
                    pt = pt->next;
                pt->next = newpassenger;
            } 
            printf("订票成功!\n");
        }
        else 
            printf("余票数不足,订票失败!\n");
    }
    else
        printf("无此车次!\n");
}

void tp() //退票函数
{
    printf("|----------------退火车票---------------|\n");
    int num, n = 2;
    while (n) {
        struct train* f = find_TrainNo();  //找到车次结点
        if (f) {
            struct node* t = find_Traveller(f); //找到旅客结点
            if (t) {
                printf("请输入退票数:");
                scanf("%d", &num);
                if (t->TicketNum > num) {
                    t->TicketNum -= num;   //修改订票数
                    t->FareSum = t->TicketNum * f->fare;//修改总票价
                }
                else { //输入退票数 num >= 预订票数
                    num = t->TicketNum;
                    if (t == f->head) {
                        f->head = f->head->next;
                        free(t);
                    }
                    else {
                        struct node* pt = f->head;
                        while (pt->next != t)
                            pt = pt->next;
                        pt->next = t->next;
                        free(t);
                    }
                }
                f->SpareTicketNum += num;//修改余票数
                printf("退票成功!\n");
                break;
            }
            else {
                printf("无此旅客!\n");
                n--;
            }
        }
        else {
            printf("无此车次!\n");
            n--;
        }
        if (n)
            printf("请重新输入车次和身份证号码!\n");
        else
            printf("输入信息错误,退票失败!\n");
    }
}

void print(struct train* pline = NULL)
{
    struct train* pt;
    printf("|----------------输出信息---------------|\n");
    if(!pline)
        pt = line; //输出所有列车信息
    else {
        pt = find_TrainNo(); //输出某一车次的信息
        if (!pt) {
            printf("无此车次的信息!\n");
            return;
        }
    }
    while (pt) {
        printf("%s %s %hd-%hd-%hd %hd:%hd %.1f %d\n", pt->terminal, pt->sequence, pt->StartTime.year, 
                                       pt->StartTime.month,pt->StartTime.day, pt->StartTime.hour, 
                                       pt->StartTime.minute, pt->fare, pt->SpareTicketNum);
        struct node* _dp = pt->head;
        while (_dp) {  //显示订票信息
            printf("%s %s %d %.2f\n", _dp->name, _dp->IDcard, _dp->TicketNum, _dp->FareSum);
            _dp = _dp->next;
        }
        if (!pline)
            pt = pt->next;
        else
            break;
    }
}
int main()
{
    input_train();
    dp();
    dp();
    dp();
    print();//不带参调用打印函数,输出所有的车次信息及订票信息
    tp();
    print(line); //带参调用打印函数,选择输出某一车次的信息及订票信息
    tp();
    print();
    tp();
    print();
    return 0;
}