C语言文件综合程序设计

不会利用c语言进行程序设计,要求如下:
1.学生档案记录录入:录入学生的学号、姓名、性别、年龄和总绩点,以记录形式保存在
文件末尾。注意:录入第一个学生的记录时要创建文件,录入其他学生的记录时只需要
打开已经创建的文件就可以
2.学生档案记录修改:允许用户选择并从文件中读取要修改的学生记录,修改指定的记录
后,能将改记录写回文件中原来的位置
3.学生档案记录删除:允许用户选择要删除的学生记录,告诉用户准备删除哪个记录,获得用户确认后从文件中删除这个记录。注意:删除一个记录后,后面的记录都得往前挪!
4.学生记录排序:对保存在文件中的记录按学号排序,排序后的记录仍写回原来的文件
5.其他功能:其他您以为适当的功能,比如按姓名、绩点排序,统计平均年龄和绩点,按姓名、年龄查找并显示学生档案资料
程序设计提示:
1.设计文件数据结构:设计文件的存储结构,将每个学生的学号、姓名、性别、年龄和总
绩点保存为一个记录,以便进行随机存取。例如:
学码12个字节,姓名8个字节,性别2个字节,年龄2个字节,总绩点3个字节,记起来一个学生的记录总共需要27个字节,记录的长度就是27个字节
2.根据所要保存的学生档案记录内容(学号、姓名、性别、年龄和总绩点),设计结构体
数据类型,结合结构体数组的运用实现文件记录的读写访间
3.将以上各功能都设计成独立的函数,在main函数中显示一个菜单,让用户选择要执行的功能,然后转而执行相应的函数
以下是我根据要求写的代码,各位帮忙修改一下或给出意见(使用的是devcppPortable编译程序)

#include<stdio.h>
#define N 100 
struct student
{
    int num;
    char name[10];
    char sex[3];
    int age,jd;
};
void func1()
{
    FILE *fp;
    int i;
    struct student s[N];
    if((fp=fopen("students.txt","ab+"))==NULL)
     {
         printf("不能打开student.txt文件\n");
         return;
     }
     printf("学生记录:\n");
     printf("学号 姓名 性别 年龄 总绩点\n");
     scanf("%d%s%s%d%d",&s[i].num,&s[i].name,&s[i].sex,&s[i].age,&s[i].jd);
     fwrite(&s[i],sizeof(struct student),1,fp);
     fclose(fp);
}
void input(struct student s[],int n)
{
    int i;
    for(i=0;i<n;i++)
    {
        printf("第%d个学生:\n",i+1);
        printf("学号 姓名 性别 年龄 总绩点\n"); 
        scanf("%d%s%s%d%d",&s[i].num,&s[i].name,&s[i].sex,&s[i].age,&s[i].jd);
    }
    
}
void output(struct student s[],int n)
{
    int i;
    printf("输出学生信息\n");
    printf("\n学号 姓名 性别 年龄 总绩点\n");
    for(i=0;i<n;i++)
    printf("%d %s %s %d %d\n",s[i].num,s[i].name,s[i].sex,s[i].age,s[i].jd);
}
int main()
{
     struct student s[N];
     int n;
     FILE *fp; 
     printf("是否进行成绩录入(Y/N):");
     char ch,temp;
     ch=getchar();
     temp=getchar();
     if((fp=fopen("students.txt","ab+"))==NULL)
     {
         printf("不能建立student.txt文件\n");
         return 0;
     }
     if(ch=='Y'||ch=='y')
     {
         printf("请输入学生人数:");
        scanf("%d",&n); 
        input(s,n);
        for(int i=0;i<n;i++)
        fwrite(&s[i],sizeof(struct student),1,fp);
        fclose(fp);
     }
     if(fwrite(&s[N],sizeof(struct student),1,fp)!=1)
     {
         printf("数据存盘失败!\n");
         return 0;
     }
     else
     printf("数据存盘完毕\n");
     void func1();
     func1();
     output(s,n);
     return 0;    
}

(那些创建文件和输出不能创建或打开文件是我查阅资料写的,我并不清楚它们是怎么运行的,如果可以的话麻车解答一下)

该回答通过自己思路及引用到GPTᴼᴾᴱᴺᴬᴵ搜索,得到内容具体如下:
你已经完成了部分功能,但还有一些问题需要解决。

首先,你需要修改 func1() 函数,使其能够在已有的文件中添加学生记录,而不是一直在文件末尾添加。你可以使用 fseek() 函数将文件指针移动到文件末尾之前的位置,然后再写入新的记录。修改后的 func1() 函数如下:

void func1()
{
    FILE *fp;
    int i;
    struct student s[N];
    if((fp=fopen("students.txt","ab+"))==NULL)
    {
        printf("不能打开student.txt文件\n");
        return;
    }
    fseek(fp, 0, SEEK_END); // 将文件指针移动到文件末尾之前的位置
    printf("学生记录:\n");
    printf("学号 姓名 性别 年龄 总绩点\n");
    scanf("%d%s%s%d%d",&s[i].num,&s[i].name,&s[i].sex,&s[i].age,&s[i].jd);
    fwrite(&s[i],sizeof(struct student),1,fp);
    fclose(fp);
}

其次,你需要添加菜单,让用户可以选择要执行的功能。你可以使用 switch 语句实现菜单功能。以下是添加菜单后的修改后的代码:

#include<stdio.h>
#define N 100 
struct student
{
    int num;
    char name[10];
    char sex[3];
    int age,jd;
};

void input(struct student s[],int n)
{
    int i;
    for(i=0;i<n;i++)
    {
        printf("第%d个学生:\n",i+1);
        printf("学号 姓名 性别 年龄 总绩点\n"); 
        scanf("%d%s%s%d%d",&s[i].num,&s[i].name,&s[i].sex,&s[i].age,&s[i].jd);
    }
}

void output(struct student s[],int n)
{
    int i;
    printf("输出学生信息\n");
    printf("\n学号 姓名 性别 年龄 总绩点\n");
    for(i=0;i<n;i++)
    printf("%d %s %s %d %d\n",s[i].num,s[i].name,s[i].sex,s[i].age,s[i].jd);
}

void add_student()
{
    FILE *fp;
    struct student s;
    if((fp=fopen("students.txt","ab+"))==NULL)
    {
        printf("不能打开student.txt文件\n");
        return;
    }
    printf("学生记录:\n");
    printf("学号 姓名 性别 年龄 总绩点\n");
    scanf("%d%s%s%d%d",&s.num,&s.name,&s.sex,&s.age,&s.jd);
    fwrite(&s,sizeof(struct student),1,fp);
    fclose(fp);
}

void modify_student()
{
    FILE *fp;
    int num, offset;
    struct student s;
    if((fp=fopen("students.txt","rb+"))==NULL)
    {
        printf("不能打开student.txt文件\n");
        return;
    }
    printf("请输入要修改的学生学号:");
    scanf("%d", &num);
    offset = (num - 1) * sizeof(struct student);
    fseek(fp, offset, SEEK_SET);
    if (fread(&s, sizeof(struct student), 1, fp) != 1)
    {
        printf("没有找到要修改的学生记录\n");
        return;
    }
    printf("该学生信息为:%d %s %s %d %d\n", s.num, s.name, s.sex, s.age, s.jd);
    printf("请输入新的学生信息:\n");
    printf("学号 姓名 性别 年龄 总绩点\n");
    scanf("%d%s%s%d%d",&s.num,&s.name,&s.sex,&s.age,&s.jd);
    fseek(fp, offset, SEEK_SET);
    fwrite(&s, sizeof(struct student), 1, fp);
    fclose(fp);
}

void delete_student()
{
    FILE *fp, *fp1;
    int num, offset, i, n;
    struct student s;
    if((fp=fopen("students.txt","rb"))==NULL)
    {
        printf("不能打开student.txt文件\n");
        return;
    }
    if((fp1=fopen("temp.txt","wb"))==NULL)
   {
        printf("不能打开temp.txt文件\n");
        return;
    }
    printf("请输入要删除的学生学号:");
    scanf("%d", &num);
    offset = (num - 1) * sizeof(struct student);
    fseek(fp, 0, SEEK_END);
    n = ftell(fp) / sizeof(struct student);
    if (num > n || num < 1)
    {
        printf("没有找到要删除的学生记录\n");
        return;
    }
    rewind(fp);
    for (i = 1; i <= n; i++)
    {
        fread(&s, sizeof(struct student), 1, fp);
        if (i != num)
            fwrite(&s, sizeof(struct student), 1, fp1);
    }
    fclose(fp);
    fclose(fp1);
    remove("students.txt");
    rename("temp.txt", "students.txt");
    printf("学生记录已删除\n");
}

void sort_student()
{
    FILE *fp;
    struct student s[N], temp;
    int i, j, n;
    if((fp=fopen("students.txt","rb+"))==NULL)
    {
        printf("不能打开student.txt文件\n");
        return;
    }
    fseek(fp, 0, SEEK_END);
    n = ftell(fp) / sizeof(struct student);
    rewind(fp);
    fread(s, sizeof(struct student), n, fp);
    for (i = 0; i < n - 1; i++)
        for (j = i + 1; j < n; j++)
            if (s[i].num > s[j].num)
            {
                temp = s[i];
                s[i] = s[j];
                s[j] = temp;
            }
    rewind(fp);
    fwrite(s, sizeof(struct student), n, fp);
    fclose(fp);
    printf("学生记录已排序\n");
}

void other_functions()
{
    // 在这里实现其他功能
    printf("其他功能\n");
}

int main()
{
    struct student s[N];
    int n, choice;
    do
    {
        printf("\n");
        printf("1. 录入学生信息\n");
        printf("2. 修改学生信息\n");
        printf("3. 删除学生信息\n");
        printf("4. 排序学生信息\n");
        printf("5. 其他功能\n");
        printf("0. 退出程序\n");
        printf("请选择要执行的功能:");
        scanf("%d", &choice);
        switch (choice)
        {
        case 1:
            add_student();
            break;
        case 2:
            modify_student();
            break;
        case 3:
            delete_student();
            break;
        case 4:
            sort_student();
            break;
        case 5:
            other_functions();
            break;
        case 0:
            printf("程序已退出\n");
            break;
        default:
            printf("无效选择,请重新选择\n");
            break;
        }
    } while (choice != 0);
    return 0;
}

注意到 delete_student() 函数中使用了一个临时文件 temp.txt,这是因为删除学生记录时需要将后面的记录都往前移动,这个操作比较麻烦,可以使用一个临时文件来简化这个过程。具体来说,我们先将要删除的学生记录之前的记录直接写入 temp.txt 中,然后跳过要删除的记录,将后面的记录继续写入 temp.txt,最后将 temp.txt 重命名为 students.txt,这样就完成了删除操作。

另外,你在 main() 函数中定义了一个 void func1(),这是不正确的语法,应该直接调用 add_student() 函数。

最后,你可以根据需要添加其他功能函数,并在菜单中添加相应选项。


如果以上回答对您有所帮助,点击一下采纳该答案~谢谢

不知道你这个问题是否已经解决, 如果还没有解决的话:

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^