文章目录
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