C语言进阶:C语言终极之战,学生管理系统的再度优化

1. 输入学生信息并输出

主要知识:动态内存、字符串指针

看一下结构体部分的知识
如果是输入结构体字符串,结构体内是不能用字符串指针的
通常做法: 申请一块动态内存存放输入的姓名,再把字符串传给结构体

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

typedef struct Student{
   
        char* name;
        int age;
        float score;
}Student;

int main(){
   
        Student s;
        char temp[1024] = {
   0};
        scanf("%s%d%f",temp,&s.age,&s.score);

        // 申请动态内存
        s.name = malloc(strlen(temp)+1);        // strlen可以读取temp中字符串的长度
        strcpy(s.name,temp);         // 再把字符串复制给结构体字符串指针

        printf("%s\n%d\n%f\n",s.name,s.age,s.score);

        free(s.name);
        s.name = NULL;
}

结果为:

zhangsan 23 91
zhangsan
23
91.000000

我们之后会经常使用申请动态内存的方法,在后续加函数能显现作用域的优势
动态内存 + 复制字符串

2. 输入多个学生信息,并设定函数

主要知识点:函数、二维指针

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

typedef struct Student{
   
        char* name;
        int age;
        float score;
}Student;

// 打印学生信息
void PrintStudents(Student* students,int n){
   
        printf("姓名\t年龄\t成绩\n");
        for(int i=0;i<n;++i){
   
                printf("%s\t%d\t%f\n",students[i].name,students[i].age,students[i].score);
        }
}

// 释放申请内存指针
void DestoryStudents(Student** pstudents,int n){
         // 使用二维指针才能释放掉主函数中指针student
        Student* students = *pstudents;
        for(int i=0;i<n;++i){
   
                free(students[i].name);
                students[i].name = NULL;
        }
        free(students);
        *pstudents = NULL;
}

// 读取学生信息
Student* ReadStudents(int n){
   
        Student* students = malloc(n*sizeof(Student));   // 申请动态内存,可以追加

        for(int i=0;i<n;++i){
   
                char temp[1024] = {
   0};
                scanf("%s%d%f",temp,&students[i].age,&students[i].score);
                // 申请动态内存
                students[i].name = malloc(strlen(temp)+1);
                strcpy(students[i].name,temp);
        }
        return students;     // 返回结构体指针
}

int main(){
   
        int n;
        scanf("%d",&n);
        Student* students = ReadStudents(n);
        PrintStudents(students,n);
        DestoryStudents(&students,n);
        printf("%p\n",students);       // 输出此时指针状态
}

结果为:

2
aaa 10 100
bbb 20 200
姓名	年龄	成绩
aaa	10	100.000000
bbb	20	200.000000
(nil)

每一个指针都要记得释放
为了释放到指针students,所以函数传参要使用二维指针
函数中直接返回结构体指针

3. 拆分,并添加读文件和写文件

主要知识点:读写文件、头文件

student.c文件内容:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include "student.h"

void PrintStudents(Student* students,int n){
   
        printf("姓名\t年龄\t成绩\n");
        for(int i=0;i<n;++i){
   
                printf("%s\t%d\t%f\n",students[i].name,students[i].age,students[i].score);
        }
}

void DestoryStudents(Student** pstudents,int n){
   
        Student* students = *pstudents;
        for(int i=0;i<n;++i){
   
                free(students[i].name);
                students[i].name = NULL;
        }
        free(students);
        *pstudents = NULL;
}

Student* ReadStudents(int n){
   
        Student* students = malloc(n*sizeof(Student));

        for(int i=0;i<n;++i){
   
                char temp[1024] = {
   0};
                scanf("%s%d%f",temp,&students[i].age,&students[i].score);
                students[i].name = malloc(strlen(temp)+1);
                strcpy(students[i].name,temp);
        }
        return students;
}

// 写入文件
bool WriteToFile(const char* path,Student* students,int n){
   
        FILE* pf = fopen(path,"w");
        if(NULL == pf){
   
                printf("%s is open error\n",path);
                return false;
        }

        for(int i=0;i<n;++i){
   
                fprintf(pf,"%s\t%d\t%f\n",students[i].name,students[i].age,students[i].score);
        }
        fclose(pf);
        pf = NULL;
        return true;
}

// 读出文件
bool ReadFromFile(const char* path,Student** pstudents,int* pn){
   
        FILE* pf = fopen(path,"r");
        if(NULL == pf){
   
                printf("%s is open error\n",path);
                return false;
        }
        Student* students = NULL;
        int count = 0;
        for(;;){
   
                int i = count;      // 用于计数
                students = realloc(students,sizeof(Student)*(count+1));    // 每次用可以在后面追加申请
                char temp[1024] = {
   0};
                int res = fscanf(pf,"%s%d%f",temp,&students[i].age,&students[i].score);
                if
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值