沉浸020903 2022-02-26 20:26 采纳率: 78.9%
浏览 87
已结题

借阅函数(668-791行)更改用户信息之后,无法存入文件,或者存很多重复的

问题遇到的现象和发生背景
问题相关代码,请勿粘贴截图
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
 
typedef struct book
{
    char bnum[10];//书籍编号 
    char bname[30];//书名 
    char bauthor[20];//作者 
    char bclassfy[10];//类别编号 
    float bprice;//价格 
    int br;//书的状态(1库中0借出) 
    struct book* next;//链表指针 
 }BookInfo;
 
 BookInfo* CreateBooksList();//创建链表
void Insert(BookInfo* head);//插入
void Delete(BookInfo* head);//删除
void Print(BookInfo* head);//浏览 
void Search(BookInfo* head);//查询 
void Update(BookInfo* head);//修改 
void Save(BookInfo* head);//保存 
void Borrowedbooks();//图书借阅 
typedef struct User
{
    char name[10];//名字
    char password[10];//密码
    char book[10];//借的书 
    struct User* next;  //下一位用户
}user;
struct bk//查找 
{
    char bnum[10];//书籍编号 
    char bname[30];//书名 
    char bauthor[20];//作者 
    char bclassfy[10];//类别编号 
    float bprice;//价格 
    int quantity;//数量 
};
struct ur//查找 
{
    char name[10];//名字
    char password[10];//密码
    char book[10];//借的书 
};
 
user* CreateusersList();//创建链表 
void userInsert(user* head);//注册用户信息 
void userDelete(user* head);//删除用户
void userprint(user* head);//浏览用户 
user* serch_username(char* name);//根据名字查找用户 
void user_login();  //用户登录
void userUpdate(user* head);//更改用户信息 
void userSave(user* head);//保存用户信息 
int usermenu();//用户系统
void adminlogin();//管理员登录 
 
//创建用户名单 
user* CreateusersList()
{
    user* head;
    head=(user*)malloc(sizeof(user));//为头结点分配空间 
    head->next=NULL;//初始化头指针
    return head; 
 } 
 //注册用户信息 
void userInsert(user* head)
{
    user *b, *p;
    char flag='Y';
    p=head;
    while (p->next !=NULL)
        p=p->next;
    //开辟新空间,存储用户信息,并加入链表
    while (flag=='Y'||flag=='y')
    {
        b=(user*)malloc(sizeof(user));//开辟新空间
        printf("请输入用户名:");//获取名称信息 
        fflush(stdin); //清空缓存区
        scanf("%s",b->name);
        printf("请输入密码:");
        fflush(stdin);
        scanf("%s",b->password);
        p->next=b;//将新增加的节点加入链表
        p=b;//指针p向后移动,指向尾结点
        b->next=NULL;
        printf("注册成功!\n");
        fflush(stdin);
        break;
     } 
     return;
 }
user* user_head;  //用户头指针
user* serch_username(char* name)  //查找用户名
{
    user* np = user_head->next;
    while (np)
    {
        if (!strcmp(np->name, name)) return np;
        np = np->next;
    }
    return NULL;
}
 
//用户登录 
void user_login()  //用户登录
{
    char name[30];
    char password[30];
    printf("请输入您的用户名(不超过10个字母):\n");
    scanf("%s", name);
    printf("请输入您的账号密码(不超过10个字母):\n");
    scanf("%s", password);
    int i,j=0;
    FILE* fp;
    struct ur u;
    fp=fopen("F:\\c语言课设\\userslist.txt","r"); 
    if(j==0)
    {
        for(i=0;i<10;i++)
    {
        fscanf(fp,"%s %s %s\n",&u.name,&u.password,&u.book);
        if(strcmp(u.name,name)==0&&strcmp(u.password,password)==0)
        {
            printf("恭喜您登录成功,即将跳转用户界面...\n");
            system("cls");
            j=1;
            usermenu();
        }
    }
    fclose(fp);
    }
    if(j==0)
    {
        printf("用户名或密码错误\n");
    }
    }
 
//
 
 
 //删除用户 
void userDelete(user* head)
{
    user *b, *p;
    char tmp[30];
    int flag;
    flag=0;
    b=head;
    p=head;
    printf("请输入要删除的用户名:");
    fflush(stdin);
    scanf("%s",tmp);
    //遍历链表
    while (p!=NULL)
    {
        if(strcmp(p->name,tmp)==0)
        {
            flag=1;
            break;
        }
        p=p->next;
     } 
    if (flag==1)
    {
        for (;b->next !=p;)
        {
            b=b->next;
        }
        b->next=p->next;
        free(p);
        printf("删除成功!\n");
    }
    else
        printf("该用户不存在!");
    return;
  } 
//浏览用户 
void userprint(user* head)
{
    user *p;
    FILE *fp;
    fp=fopen("F:\\c语言课设\\userslist.txt","r");
    rewind(fp);
    char ch=fgetc(fp);
    while(ch!=-1)
    {
        putchar(ch);
        ch=fgetc(fp);
    }
    fclose(fp);
 
 }
//查找用户 
void userSearch(user* head)
{
    user *p;
    char tmp[30];
    int flag=0;
    p=head;
    if(head==NULL||head->next==NULL)
    {
        printf("清单为空!\n");
    }
    else
    {
        printf("请输入用户名:");
        fflush(stdin);
        scanf("%s",tmp);
        while(p->next !=NULL)
        {
            p=p->next;
            if(strcmp(p->name,tmp)==0)
            {
                flag=1;
                printf("用户名:%s\n",p->name);
                return;
            }
            if(p->next==NULL)
            {
                printf("\n查询完毕!");
            }
            
        }
        if(flag==0)
        {
            printf("没有找到该用户!\n",tmp);
        }
    }
    return;
 }
 
//保存用户信息 
void userSave(user* head)
{
    user *p;
    FILE *fp;
    p=head;
    //以只写的方式打开文件
    fp=fopen("F:\\c语言课设\\userslist.txt","a");
    while (p->next !=NULL)
    {
        p=p->next;
        fprintf(fp,"%-6s %-10s\n",p->name,p->password);
    }
    fclose(fp);
    printf("保存成功!\n");
    printf("数据已成功保存到F:\\c语言课设\\userslist.txt\n");
     
 }   
int menu();//菜单 
 
//创建书单
BookInfo* CreateBooksList()
{
    BookInfo* head;
    head=(BookInfo*)malloc(sizeof(BookInfo));//为头结点分配空间 
    head->next=NULL;//初始化头指针
    return head; 
 } 
//插入记录
void Insert(BookInfo* head)
{
    BookInfo *b, *p;
    char flag='Y';
    p=head;
    while (p->next !=NULL)
        p=p->next;
    //开辟新空间,存储书籍信息,并加入链表
    while (flag=='Y'||flag=='y')
    {
        b=(BookInfo*)malloc(sizeof(BookInfo));//开辟新空间
        printf("请输入图书编号:");//获取书籍信息 
        fflush(stdin); //清空缓存区
        scanf("%s",b->bnum);
        printf("请输入书名:");
        fflush(stdin);
        scanf("%s",b->bname);
        printf("请输入作者:");
        fflush(stdin);
        scanf("%s",b->bauthor);
        printf("请输入类别编号:");
        fflush(stdin);
        scanf("%s",b->bclassfy);
        printf("请输入图书价格:");
        fflush(stdin);
        scanf("%f",&b->bprice);
        b->br=1;
        p->next=b;//将新增加的节点加入链表
        p=b;//指针p向后移动,指向尾结点
        b->next=NULL;
        printf("添加成功!\n继续添加?(Y/N):");
        fflush(stdin);
        scanf("%c",&flag);
        if(flag=='N'||flag=='n')break;
        else if (flag=='Y'||flag=='y')continue; 
     } 
     return;
 }
//删除记录
void Delete(BookInfo* head)
{
    BookInfo *b, *p;
    char tmp[30];
    int flag;
    flag=0;
    b=head;
    p=head;
    printf("请输入要删除的书籍名:");
    fflush(stdin);
    scanf("%s",tmp);
    //遍历链表
    while (p!=NULL)
    {
        if(strcmp(p->bname,tmp)==0)
        {
            flag=1;
            break;
        }
        p=p->next;
     } 
    if (flag==1)
    {
        for (;b->next !=p;)
        {
            b=b->next;
        }
        b->next=p->next;
        free(p);
        printf("删除成功!\n");
    }
    else
        printf("该书不存在!");
    return;
  }  
//浏览书单
void print(BookInfo* head)
{
    BookInfo *p;
    FILE *fp;
    fp=fopen("F:\\c语言课设\\bookslist.txt","r");
    rewind(fp);
    printf("-----------------------------------------------------\n");
    printf("|编号   |书名   |作者    |类别编号   |价格   |数量  |\n");
    printf("-----------------------------------------------------\n");
    char ch=fgetc(fp);
    while(ch!=-1)
    {
        putchar(ch);
        ch=fgetc(fp);
    }
    fclose(fp);
 
 } 
//查找书籍
void Search(BookInfo* head)
{
    BookInfo *p;
    char tmp[30];
    int flag=0;
    p=head;
    if(head==NULL||head->next==NULL)
    {
        printf("清单为空!\n");
    }
    else
    {
        printf("请输入书籍名:");
        fflush(stdin);
        scanf("%s",tmp);
        while(p->next !=NULL)
        {
            p=p->next;
            if(strcmp(p->bname,tmp)==0)
            {
                flag=1;
                printf("编号:%s\n 书名:《%s》\n作者:%s\n分类:%s\n价格:%.2f\n",p->bnum,p->bname,p->bauthor,p->bclassfy,p->bprice);
                return;
            }
            if(p->next==NULL)
            {
                printf("\n查询完毕!");
            }
            
        }
        if(flag==0)
        {
            printf("没有找到《%s》!\n",tmp);
        }
    }
    return;
 }
void creat_user_list(char* name, char* password)  //创建用户链表
{
    user* head;
    user* np = (user*)malloc(sizeof(user));
    np = user_head;
    while (np->next) np = np->next;
    User* tp = (user*)malloc(sizeof(user));
    strcpy(tp->name, name);
    strcpy(tp->password, password);
    tp->next = NULL;
    np->next = tp;
    userSave(head);
    
}
//修改信息
void Update(BookInfo* head)
{
    BookInfo *p;
    int flag=0;
    char tmp[30];
    p=head;
    printf("请输入书名:");
    fflush(stdin);
    scanf("%s",tmp);
    while(p->next!=NULL)
    {
        p=p->next;
        if(strcmp(p->bname,tmp)==0)
        {
            flag=1;//标志找到所要修改修改的书籍
            printf("请输入编号:");
            fflush(stdin);
            scanf("%s",p->bnum);
            printf("请输入书名:");
            fflush(stdin);
            scanf("%s",p->bname);
            printf("请输入作者:");
            fflush(stdin);
            scanf("%s",p->bauthor);
            printf("请输入类别编号:");
            fflush(stdin);
            scanf("%s",p->bclassfy);
            printf("请输入价格:");
            fflush(stdin);
            scanf("%s",p->bprice);
 
        }
    }
    if (flag==0)
    {
        printf("没有找到《%s》!\n",tmp);
    }
    return;
 } 
 
//保存书单到文件
void Save(BookInfo* head)
{
    BookInfo *p;
    FILE *fp;
    p=head;
    //以只写的方式打开文件
    fp=fopen("F:\\c语言课设\\bookslist.txt","a");
    while (p->next !=NULL)
    {
        p=p->next;
        fprintf(fp,"%-6s %-10s %-10s %-10s %.2f %d\n",p->bnum,p->bname,p->bauthor,p->bclassfy,p->bprice,p->br);
    }
    fclose(fp);
    printf("保存成功!\n");
    printf("数据已成功保存到F:\\c语言课设\\bookslist.txt\n");
     
 } 
void user_register()  //用户注册
{
    char name[30];
    printf("请输入您需要注册的用户名(不超过25个字母):\n");
    scanf("%s", name);
    User* account;
    while (account = serch_username(name), account != NULL)
    {
        printf("该用户名已存在,请重新输入!\n");
        scanf("%s", name);
    }
    printf("请输入您的账号密码(不超过25个字母):\n");
    char password[30];
    scanf("%s", password);
    creat_user_list(name, password);
    printf("恭喜您注册成功!\n");
}
//菜单
void main_menu()  //主菜单
{
    user *head;
    BookInfo *headd;
    int a,b,c,d;
    head=NULL;
    while (1)
    {
        printf("+---------------------------------------------+\n");
        printf("*            欢迎进入本图书管理系统!          *\n");
        printf("*         请输入选项前的数字以确认操作!      *\n");
        printf("*               1、用户注册                   *\n");
        printf("*               2、用户登陆                   *\n");
        printf("*               3、管理员登陆                 *\n");
        printf("*               0、退出               *\n");
        printf("+---------------------------------------------+\n");
        int op; 
        scanf("%d", &op); 
        switch (op)
        {
        case 1: if(head==NULL)
                {
                    head=CreateusersList();
                }
                userInsert(head);
                userSave(head);
                break;
        case 2: user_login();
                
                break;
        case 3: adminlogin();  break;
        case 0: exit(0); break;
        default: printf("错误的指令,请重新输入!\n"); 
        }
    }
}
int adminmenu()
{
    int sec;
    user *head;
    BookInfo *headd;
    headd=NULL;
    printf("                    管理员系统                     \n");
    printf("-----------------------------------------------------\n");
    printf("                   1-图书信息录入\n");
    printf("                   2-图书信息浏览\n");
    printf("                   3-图书信息查询\n");
    printf("                   4-图书信息修改\n");
    printf("                   5-图书信息删除\n");
    printf("                   6-图书信息保存\n");
    printf("                   7-删除用户\n");
    printf("                   8-浏览用户\n");
    printf("                   9-退出\n");
    printf("-----------------------------------------------------\n");
    printf("请选择:");
    fflush(stdin);
    scanf("%d",&sec);
    switch (sec)
    {
        case 1:
            if(headd==NULL)
            {
                headd=CreateBooksList();
            }
            Insert(headd);
            Save(headd); 
            break;
        case 2:print(headd); break;
        case 3:Search(headd); break;
        case 4:Update(headd); break;
        case 5:Delete(headd); break;
        case 6:Save(headd); break;
        case 7:
        case 8:
        case 9:exit(0); break;
    }
    while(sec>7||sec<0)
    {
        printf("选择有误!\n请重新输入:");
        scanf("%d",&sec);
     } 
    return sec;
 }
 //管理员登录 
void adminlogin()
{
    char tmp[30];
    char tmpp[30];
    int flag=0;
        printf("请输入用户名:");
        fflush(stdin);
        scanf("%s",tmp);
        printf("请输入密码:");
        fflush(stdin);
        scanf("%s",tmpp);
            if(strcmp("dyq",tmp)==0&&strcmp("123",tmpp)==0)
            {
                flag=1;
                printf("登陆成功\n");
                system("cls");
                adminmenu();
                
            }
            
        if(flag==0)
        {
            printf("用户名或密码错误!\n",tmp);
        }
        
    return;
 }
 int usermenu()
 {
    user *head;
    BookInfo *headd;
    int b;
    printf("                    用户系统                     \n");
    printf("-----------------------------------------------------\n");
    printf("                   1-图书信息浏览\n");
    printf("                   2-图书信息查询\n");
    printf("                   3-图书借阅\n");
    printf("                   4-图书归还\n");
    printf("                   5-保存用户信息\n");
    printf("                   6-退出\n");
    printf("-----------------------------------------------------\n");
    printf("请选择:");
    fflush(stdin);
    scanf("%d",&b);
    switch (b)
                {
                    case 1:print(headd); usermenu();
                    case 2:Search(headd); usermenu();
                    case 3:Borrowedbooks(); usermenu();
                    case 4:
                    case 5:userSave(head); usermenu();
                    case 6:exit(0); break;
                }
    while(b>6||b<0)
    {
        printf("选择有误!\n请重新输入:");
        scanf("%d",&b);
     } 
    return b;    
 }
int tjzs()//统计图书文本个数
{
    char f[10]={0},ch;
    int cap=0;//行数
    FILE *fp;
    fp=fopen("F:\\c语言课设\\bookslist.txt","r");
    gets(f);
    while(!feof(fp))
    {
        if((ch=getc(fp))!=EOF)
        {
            if((ch=getc(fp))=='\n')
                cap++;
        }
    }
    cap++;
    fclose(fp);
    return cap;
}
int tjyh()//统计图书文本个数
{
    char f[10]={0},ch;
    int cap=0;//行数
    FILE *fp;
    fp=fopen("F:\\c语言课设\\userslist.txt","r");
    gets(f);
    while(!feof(fp))
    {
        if((ch=getc(fp))!=EOF)
        {
            if((ch=getc(fp))=='\n')
                cap++;
        }
    }
    cap++;
    fclose(fp);
    return cap;
}
 
void Borrowedbooks()//借书函数
{
    FILE *fp,*fp3;
    user *headd=NULL;
    user *p3,*p4,*p5;
    BookInfo *head=NULL;
    BookInfo *p,*p1,*p2;
    fp=fopen("F:\\c语言课设\\bookslist.txt","r");
    int i,loop,k,h,n=0,flag=0,s=0;
    int br=0;
    float bprice=0;
    char bnum[10]={'\0'},bname[30]={'\0'},bauthor[20]={'\0'},bclassfy[10]={'\0'},
         name[30]={'\0'},password[30]={'\0'},book[10]={'\0'};//book书的编号 
    char hit=0;
        printf("\n请输入要借阅书的编号:\n请输入:");
        scanf("%s",book);
    k=tjzs()-2;//统计图书馆文件个数
    fscanf(fp,"%s%s%s%s%f%d\n",bnum,bname,bauthor,bclassfy,&bprice,&br);
    p1=p2=(BookInfo*)malloc(sizeof(BookInfo));
    head=p1;
    strcpy(p1->bnum,bnum);//复制书号
    strcpy(p1->bname,bname);//复制书名
    strcpy(p1->bauthor,bauthor);//复制作者
    strcpy(p1->bclassfy,bclassfy);//复制出版社
    p1->br=br;//复制书的状态 
    p1->bprice=bprice;//复制单价
    for (i=0;i<k;i++)//先将图书信息建立链表,更改库存
        {
            fscanf(fp,"%s%s%s%s%f%d\n",bnum,bname,bauthor,bclassfy,&bprice,&br);
            p2->next=p1;
            p2=p1;
            p1=(BookInfo*)malloc(sizeof(BookInfo));
            strcpy(p1->bnum,bnum);//复制书号
            strcpy(p1->bname,bname);//复制书名
            strcpy(p1->bauthor,bauthor);//复制作者
            strcpy(p1->bclassfy,bclassfy);//复制出版社
            p1->br=br;//复制书的状态 
            p1->bprice=bprice;//复制单价
            p2->next=p1;
            p1->next=NULL;
         }
        fclose(fp);
        p=head;
    
    for (;p!=NULL;)
    {
        if(!(strcmp(p->bnum,book))&&p->br==1)//判断要借书的是否存在,标记等于1,存在库存减一
        {
            
            flag=1;
            p->br=0;
         }
        p=p->next;
  }
    if(flag)//把状态变化后的链表存入文件
    {
 
        fp=fopen("F:\\c语言课设\\bookslist.txt","w");
        fclose(fp);
        fp=fopen("F:\\c语言课设\\bookslist.txt","a");
        p=head;
 
        for(;p !=NULL;)
        {
            fprintf(fp,"%-10s %-10s %-10s %-10s %.2f %d\n",p->bnum,p->bname,p->bauthor,p->bclassfy,p->bprice,p->br);
            p=p->next;
        }
        free(p);
        fclose(fp);
        
 
//建读者文件夹存入借书信息
    fp3=fopen("F:\\c语言课设\\userslist.txt","r");
    fscanf(fp3,"%s%s%s\n",name,password,book);
    p4=p5=(user*)malloc(sizeof(user));
    headd=p4;
    strcpy(p4->name,name);//复制用户名 
    strcpy(p4->password,password);//复制密码 
    strcpy(p4->book,book);//复制借阅情况 
    h=tjyh()-1;
    for (i=1;i<h;i++)//先将用户信息建立链表,更改借阅情况 
        {
            fscanf(fp3,"%s%s%s\n",name,password,book);
            p5->next=p4;
            p5=p4;
            p4=(user*)malloc(sizeof(user));
            strcpy(p4->name,name);//复制用户名 
            strcpy(p4->password,password);//复制密码 
            strcpy(p4->book,book);//复制借阅情况 
            p5->next=p4;
            p4->next=NULL;
         }
        fclose(fp3);
        p3=headd;
    
    for (;p3!=NULL;)
    {
        fp3=fopen("F:\\c语言课设\\userslist.txt","w");
        fclose(fp);
        fp=fopen("F:\\c语言课设\\userslist.txt","a");
        p3=headd;
 
        for(;p3!=NULL;)
        {
            fprintf(fp,"%-10s %-10s %-10s\n",p3->name,p3->password,p3->book);
            p3=p3->next;
        }
        free(p3);
        fclose(fp3);

  }
        printf("借书成功!请两个月内归还!!!按任意键返回\n");
        usermenu();
   }
    else
    {
        if(flag!=0)
        printf("此书已被借完!按任意键返回!");//否则输出此书已被借完
        else
        printf("查找无此书!按任意键返回");
    }
        usermenu();//调用借阅系统
 
}
 
int main()
{
    user *head;
    BookInfo *headd;
    int a,b,c,d;
    head=NULL;
    for (;;)
    {
        main_menu();
    }
    return 0;
}

运行结果及报错内容
我的解答思路和尝试过的方法

我试过把tjyh函数的结果+1或者-1,都没用

我想要达到的结果

借阅函数可以正常运行,现在借阅完书单里是正常的,用户信息不正常

  • 写回答

2条回答 默认 最新

  • 关注

    687行,head=p1;改成head=p2;
    688-693行的p1都改成p2
    698行的 p2=p1放在for循环的最后一句

    // 686 - 711行代码修改如下:
    p1=p2=(BookInfo*)malloc(sizeof(BookInfo));
        head=p2;
        strcpy(p2->bnum,bnum);//复制书号
        strcpy(p2->bname,bname);//复制书名
        strcpy(p2->bauthor,bauthor);//复制作者
        strcpy(p2->bclassfy,bclassfy);//复制出版社
        p2->br=br;//复制书的状态 
        p2->bprice=bprice;//复制单价
        for (i=0;i<k;i++)//先将图书信息建立链表,更改库存
        {
            fscanf(fp,"%s%s%s%s%f%d\n",bnum,bname,bauthor,bclassfy,&bprice,&br);
            p2->next=p1;
            //p2=p1; //放在最后面
            p1=(BookInfo*)malloc(sizeof(BookInfo));
            strcpy(p1->bnum,bnum);//复制书号
            strcpy(p1->bname,bname);//复制书名
            strcpy(p1->bauthor,bauthor);//复制作者
            strcpy(p1->bclassfy,bclassfy);//复制出版社
            p1->br=br;//复制书的状态 
            p1->bprice=bprice;//复制单价
            //p2->next=p1;//这一句重复了,删掉即可
            p1->next=NULL;
    
            p2=p1;
        }
        fclose(fp);
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(1条)

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 2月28日
  • 已采纳回答 2月26日
  • 创建了问题 2月26日

悬赏问题

  • ¥15 winform的chart曲线生成时有凸起
  • ¥15 msix packaging tool打包问题
  • ¥15 finalshell节点的搭建代码和那个端口代码教程
  • ¥15 用hfss做微带贴片阵列天线的时候分析设置有问题
  • ¥15 Centos / PETSc / PETGEM
  • ¥15 centos7.9 IPv6端口telnet和端口监控问题
  • ¥20 完全没有学习过GAN,看了CSDN的一篇文章,里面有代码但是完全不知道如何操作
  • ¥15 使用ue5插件narrative时如何切换关卡也保存叙事任务记录
  • ¥20 海浪数据 南海地区海况数据,波浪数据
  • ¥20 软件测试决策法疑问求解答