C语言图书馆里之排序功能闪退 无法实现

C语言图书馆里之排序功能闪退 无法实现 希望有人可以帮我解答以及改正我的第六个也就是排序功能的BUG{排序的函数在最后}
下面是我的代码 : 我用的是VS2019

img

评论非法,代码在这里贴一份。代码修改如下:


//#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<conio.h>
#include<windows.h>
#include<dos.h>
#define LEN sizeof(book)
#define FORMAT "%-10d%-8s%-5s%-10d%-5d\n"
#define DATA stu[i].id, stu[i].name, stu[i].author, stu[i].publish, stu[i].price

typedef struct book //确认结构体
{

    char id[8];
    char name[31];
    char author[27];
    char publish[31];
    double price;

}book;

//int n = 0; //修改,你下面的代码都是重新读取的文件,所以这里全局变量就别要了
//book stu[100]; 

void Menu1();//标题函数

void Menu2();//菜单函数

void WriteToFile();//书籍信息输入的函数

void ReadFromFile();//显示所有信息的函数

void QueryFile();//书籍的查询函数

void ModifyFile();//书籍的修改函数

void DeletFile();//删除数据的函数
void showall();//排序数据的函数

int main()
{
    int select;

    do
    {
        Menu1();
        Menu2();
        scanf("%d", &select);
        switch (select)
        {
        case 1:
            WriteToFile();
            break;

        case 2:
            ReadFromFile();
            break;

        case 3:
            QueryFile();
            break;

        case 4:
            ModifyFile();
            break;

        case 5:
            DeletFile();
            break;

        case 6:
            showall();
            break;

        default:
            printf("退出程序!");
            exit(0);
            break;
        }
    } while ((select == 1 || select == 2) || (select == 3 || select == 4) || (select == 5) || (select == 6));

    return 0;
}//利用switch函数进行菜单的选择

void Menu1()
{

    system("mode con cols=80 lines=30");
    system("color D7");
    printf("**********欢迎使用俄罗斯攻打乌克兰导弹系统***********\n");

}//标题函数1

void Menu2()
{
    printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
    printf("\t\t1.录入图书\t\t\n");
    printf("\t\t2.显示图书\t\t\n");
    printf("\t\t3.查询图书\t\t\n");
    printf("\t\t4.修改图书\t\t\n");
    printf("\t\t5.删除图书\t\t\n");
    printf("\t\t6.排序图书\t\t\n");
    printf("\t\t0.退出\t\t\n");
    printf("\t\t输入你的操作:");

}//标题函数2

void WriteToFile()
{
    FILE* fp = NULL;
    book stu;
    char flag = 'y';
    fp = fopen("book1.dat", "ab+");//打开文件

    if (fp == NULL)
    {
        printf("文件打开失败!\n");
        exit(1);//1表示在有错的方式退出程序
    }

    while ((flag == 'y' || flag == 'Y'))
    {
        system("cls");
        Menu1();

        printf("请输入图书id:");
        scanf("%s", stu.id);

        printf("请输入书名:");
        scanf("%s", stu.name);

        printf("请输入书籍作者:");
        scanf("%s", stu.author); //修改1  这里不需要&

        printf("请输入出版社:");
        scanf("%s", stu.publish);//修改2  这里不需要&

        printf("请输入价格:");
        scanf("%lf", &stu.price);


        fwrite(&stu, LEN, 1, fp);
        fflush(stdin);

        //n++;
        printf("继续输入吗?继续请输入y或Y:");
        //修改3,fflush以后已经清空了,直接读取就可以了
        flag = getchar();
        getchar(); //吸收回车符
        //scanf("%c", &flag);
    }

    fclose(fp);//关闭文件
    return;
}//图书添加的函数

void ReadFromFile()
{
    system("cls");
    Menu1();
    FILE* fp = NULL;
    book stu;
    fp = fopen("book1.dat", "rb");

    if (fp == NULL)
    {
        printf("文件打开失败");
        exit(1);
    }
    printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
    printf("         id\t\t书名\t\t作者\t\t出版社\t\t价格");

    fseek(fp, 0, SEEK_SET);

    while (!feof(fp))
    {
        if (fread(&stu, LEN, 1, fp))
        {
            printf("%15s\t\t%s\t\t%13s%20s\t%0.1f\n", stu.id, stu.name, stu.author, stu.publish, stu.price);
        }
    }

    printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
    system("pause");
    system("cls");
    fclose(fp);
    return;
}

void QueryFile()
{
    system("cls");
    Menu1();
    book stu;
    char x[8];
    int flag = 0;
    FILE* fp;

    printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
    printf("\t\t请输入图书id:");
    scanf("%s", x);
    printf("  ID  书名    作者     出版社     价格\n");

    fp = fopen("book1.dat", "rb");

    if (fp == NULL)
    {
        printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
        printf("错误\n");
        printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
        return;
    }

    fseek(fp, 0, SEEK_SET);
    while (fread(&stu, LEN, 1, fp))
    {

        if (strcmp(x, stu.id) == 0)
        {
            printf("%3s  %5s  %5s    %10s %5.2lf\n", stu.id, stu.name, stu.author, stu.publish, stu.price);
            flag = 1;
        }
        //修改4,这个放在while外面
        /*if (flag = 0)
        {
        printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
        printf("没有图书信息");
        printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
        }*/
    }
    if (flag = 0)
    {
        printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
        printf("没有图书信息");
        printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
    }else    
        printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
    fclose(fp);
    system("pause");
    system("cls");
    return;
}

void ModifyFile()
{
    system("cls");
    Menu1();
    book stu;
    FILE* fp;
    char x[8];
    int flag =0;

    printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
    printf("请输入图书id:");
    scanf("%s", x);

    fp = fopen("book1.dat", "rb+");

    if (fp == NULL)
    {
        printf("文件打开失败");
        exit(1);
    }

    fseek(fp, 0, SEEK_SET);

    //修改,下面的代码大改了
    while (fread(&stu, LEN, 1, fp))
    {
        if (strcmp(x, stu.id) == 0)
        {
            flag = 1;
            printf("请重新输入图书id:   ");
            scanf("%s", stu.id);

            printf("请重新输入书名:    ");
            scanf("%s", stu.name);

            printf("请重新输入书籍作者  : ");
            scanf("%s", stu.author); //修改,不需要&

            printf("请重新输入图书出版社  : ");
            scanf("%s", stu.publish);//修改,不需要&

            printf("请重新输入图书价格 :   ");
            scanf("%lf", &stu.price);
            printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
            fflush(stdin);
            fseek(fp, 0 - LEN, SEEK_CUR);
            fwrite(&stu, LEN, 1, fp);
            fclose(fp);
            break; //修改,这里结束循环
        }
    }

        if (flag==0) //这里最后不要用feof(fp),如果最后一个元素匹配的话,这里也是满足的
        {
            printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
            printf("没有图书信息");
            printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
        }

    

    system("pause");
    system("cls");
    return;
}


//
//void showall()
//{
//    FILE* fp;
//    int i, m = 0;
//    fp = fopen("data", "ab+");
//    while (!feof(fp))
//    {
//        if (fread(&stu, LEN, 1, fp) == 1)
//            m++;
//    }
//    printf(" ID  书名    作者     出版社     价格\n ");
//    for (i = 0; i <= 10; i++)
//    {
//        printf("FORMAT,DATA");
//    }
//}

void DeletFile()
{
    system("cls");
    Menu1();
    book s;
    FILE* fp;
    char a[10];
    fp = fopen("book1.dat", "rb+");

    if (fp == NULL)
    {
        printf("打开文件错误!!!\n");
        exit(1);
    }

    printf("\n请输入图书ID:");
    scanf("%s", a);
    printf("\n\t\t\t删除成功\n");

    fseek(fp, 0, SEEK_SET);
    FILE* fp1;
    fp1 = fopen("linshi.dat", "ab+");//读写新建一个临时文件

    while (fread(&s, LEN, 1, fp))//从原文件读一个结点
    {
        if (strcmp(a, s.id) != 0)//不是要删除的内容
        {
            fwrite(&s, LEN, 1, fp1);
        }
    }

    fclose(fp);
    fclose(fp1);
    remove("book1.dat");//删除原文件
    rename("linshi.dat", "book1.dat");//重命名为原文件

    fflush(stdin);
    system("pause");
    system("cls");
    return;
}

void showall()
{
    int i, j,n=0;
    struct book t,stu[100];

    //先读取数据
    FILE* fp = fopen("book1.dat", "rb");

    if (fp == NULL)
    {
        printf("文件打开失败");
        exit(1);
    }
    while (!feof(fp))
    {
        if (fread(&stu[n], LEN, 1, fp))
        {
            n++;
        }
    }

    //排序
    for (i = 0; i < n-1; i++)
    {
        for (j = 0; j < n - 1 - i; j++)
        {
            if (strcmp(stu[j].id, stu[j + 1].id) > 0)
            {
                t = stu[j];
                stu[j] = stu[j + 1];
                stu[j + 1] = t;
            }
        }
    }
    printf("********************************排序的结果为:***********************************");
    printf("\n的序号为(由小到大排列):\n");
    printf(" \n");
    for (i = 0; i < n; i++)     //利用循环输出排序后的信息
    {
        printf("%10s%30s%30s%30s%5.1f\n", stu[i].id, stu[i].name, stu[i].author, stu[i].publish, stu[i].price);

    }
    system("pause");
    system("cls");
}

闪退一般是指针非法操作或者数组越界访问导致的
找了半天也没看见你排序函数在哪,你把排序函数代码贴出来就可以了


#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<conio.h>
#include<windows.h>
#include<dos.h>
#define LEN sizeof(book)
#define FORMAT "%-10d%-8s%-5s%-10d%-5d\n"
#define DATA stu[i].id, stu[i].name, stu[i].author, stu[i].publish, stu[i].price

typedef struct book //确认结构体
{

    char id[8];
    char name[31];
    char author[27];
    char publish[31];
    double price;

}book;

int n = 0;
book stu[100];

void Menu1();//标题函数

void Menu2();//菜单函数

void WriteToFile();//书籍信息输入的函数

void ReadFromFile();//显示所有信息的函数

void QueryFile();//书籍的查询函数

void ModifyFile();//书籍的修改函数

void DeletFile();//删除数据的函数
void  showall();//排序数据的函数

int main()
{
    int select;

    do
    {
        Menu1();
        Menu2();
        scanf("%d", &select);
        switch (select)
        {
        case 1:
            WriteToFile();
            break;

        case 2:
            ReadFromFile();
            break;

        case 3:
            QueryFile();
            break;

        case 4:
            ModifyFile();
            break;

        case 5:
            DeletFile();
            break;

        case 6:
            showall();
            break;

        default:
            printf("退出程序!");
            exit(0);
            break;
        }
    } while ((select == 1 || select == 2) || (select == 3 || select == 4) || (select == 5) || (select == 6));

    return 0;
}//利用switch函数进行菜单的选择

void Menu1()
{

    system("mode con cols=80 lines=30");
    system("color D7");
    printf("**********欢迎使用俄罗斯攻打乌克兰导弹系统***********\n");

}//标题函数1

void Menu2()
{
    printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
    printf("\t\t1.录入图书\t\t\n");
    printf("\t\t2.显示图书\t\t\n");
    printf("\t\t3.查询图书\t\t\n");
    printf("\t\t4.修改图书\t\t\n");
    printf("\t\t5.删除图书\t\t\n");
    printf("\t\t6.排序图书\t\t\n");
    printf("\t\t0.退出\t\t\n");
    printf("\t\t输入你的操作:");

}//标题函数2

void WriteToFile()
{
    FILE* fp = NULL;
    book stu;
    char flag = 'y';
    fp = fopen("book1.dat", "ab+");//打开文件

    if (fp == NULL)
    {
        printf("文件打开失败!\n");
        exit(1);//1表示在有错的方式退出程序
    }

    while ((flag == 'y' || flag == 'Y'))
    {
        system("cls");
        Menu1();

        printf("请输入图书id:");
        scanf("%s", stu.id);

        printf("请输入书名:");
        scanf("%s", stu.name);

        printf("请输入书籍作者:");
        scanf("%s", &stu.author);

        printf("请输入出版社:");
        scanf("%s", &stu.publish);

        printf("请输入价格:");
        scanf("%lf", &stu.price);


        fwrite(&stu, LEN, 1, fp);
        fflush(stdin);

        n++;
        printf("继续输入吗?继续请输入y或Y:");
        getchar();
        scanf("%c", &flag);
    }

    fclose(fp);//关闭文件
    return;
}//图书添加的函数

void ReadFromFile()
{
    system("cls");
    Menu1();
    FILE* fp = NULL;
    book stu;
    fp = fopen("book1.dat", "rb");

    if (fp == NULL)
    {
        printf("文件打开失败");
        exit(1);
    }
    printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
    printf("         id\t\t书名\t\t作者\t\t出版社\t\t价格");

    fseek(fp, 0, SEEK_SET);

    while (!feof(fp))
    {
        if (fread(&stu, LEN, 1, fp))
        {
            printf("%15s\t\t%s\tt\%13s\%20s\t%0.1f\n", stu.id, stu.name, stu.author, stu.publish, stu.price);
        }
    }

    printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
    system("pause");
    system("cls");
    fclose(fp);
    return;
}

void QueryFile()
{
    system("cls");
    Menu1();
    book stu;
    char x[8];
    int flag = 0;
    FILE* fp;

    printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
    printf("\t\t请输入图书id:");
    scanf("%s", x);
    printf("  ID  书名    作者     出版社     价格\n");

    fp = fopen("book1.dat", "rb");

    if (fp == NULL)
    {
        printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
        printf("错误\n");
        printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
        return;
    }

    fseek(fp, 0, SEEK_SET);
    while (fread(&stu, LEN, 1, fp))
    {

        if (strcmp(x, stu.id) == 0)
        {
            printf("%3s  %5s  %5s    %10s %5.2lf\n", stu.id, stu.name, stu.author, stu.publish, stu.price);
            flag = 1;
        }

        if (flag = 0)
        {
            printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
            printf("没有图书信息");
            printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
        }
    }

    printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
    fclose(fp);
    system("pause");
    system("cls");
    return;
}

void ModifyFile()
{
    system("cls");
    Menu1();
    book stu;
    FILE* fp;
    char x[8];

    printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
    printf("请输入图书id:");
    scanf("%s", x);

    fp = fopen("book1.dat", "rb+");

    if (fp == NULL)
    {
        printf("文件打开失败");
        exit(1);
    }

    fseek(fp, 0, SEEK_SET);
    while (fread(&stu, LEN, 1, fp))
    {

        if (strcmp(x, stu.id) == 0)
        {
            printf("请重新输入图书id:   ");
            scanf("%s", stu.id);

            printf("请重新输入书名:    ");
            scanf("%s", stu.name);

            printf("请重新输入书籍作者  : ");
            scanf("%s", &stu.author);

            printf("请重新输入图书出版社  : ");
            scanf("%s", &stu.publish);

            printf("请重新输入图书价格 :   ");
            scanf("%lf", &stu.price);
            printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
            fflush(stdin);
            fseek(fp, 0 - LEN, SEEK_CUR);
            fwrite(&stu, LEN, 1, fp);
            fclose(fp);
        }

        if (feof(fp))
        {
            printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
            printf("没有图书信息");
            printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
        }

    }

    system("pause");
    system("cls");
    return;
}


//
//void showall()
//{
//    FILE* fp;
//    int i, m = 0;
//    fp = fopen("data", "ab+");
//    while (!feof(fp))
//    {
//        if (fread(&stu, LEN, 1, fp) == 1)
//            m++;
//    }
//    printf(" ID  书名    作者     出版社     价格\n ");
//    for (i = 0; i <= 10; i++)
//    {
//        printf("FORMAT,DATA");
//    }
//}

void DeletFile()
{
    system("cls");
    Menu1();
    book s;
    FILE* fp;
    char a[10];
    fp = fopen("book1.dat", "rb+");

    if (fp == NULL)
    {
        printf("打开文件错误!!!\n");
        exit(1);
    }

    printf("\n请输入图书ID:");
    scanf("%s", a);
    printf("\n\t\t\t删除成功\n");

    fseek(fp, 0, SEEK_SET);
    FILE* fp1;
    fp1 = fopen("linshi.dat", "ab+");//读写新建一个临时文件

    while (fread(&s, LEN, 1, fp))//从原文件读一个结点
    {
        if (strcmp(a, s.id) != 0)//不是要删除的内容
        {
            fwrite(&s, LEN, 1, fp1);
        }
    }

    fclose(fp);
    fclose(fp1);
    remove("book1.dat");//删除原文件
    rename("linshi.dat", "book1.dat");//重命名为原文件

    fflush(stdin);
    system("pause");
    system("cls");
    return;
}

void showall()
{
    int i, j;
    struct book t;
    for (i = 0; i < n; i++)
        for (j = 0; j < n - 1 - i; j++)
            if (strcmp(stu[j].id, stu[j + 1].id) > 0)
            {
                t = stu[j];
                stu[j] = stu[j + 1];
                stu[j + 1] = t;
            }
    printf("********************************排序的结果为:***********************************");
    printf("\n的序号为(由小到大排列):\n");
    printf(" \n");
    for (i = 0; i < n; i++)     //利用循环输出排序后的信息
    {
        printf("%3sd%3s%3s%5s%5.1f\n", stu[i].id, stu[i].name, stu[i].author, stu[i].publish, stu[i].price);
        
    }system("pause");
    system("cls");
}
您好,我是有问必答小助手,您的问题已经有小伙伴帮您解答,感谢您对有问必答的支持与关注!
PS:问答VIP年卡 【限时加赠:IT技术图书免费领】,了解详情>>> https://vip.csdn.net/askvip?utm_source=1146287632