You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在已完成的C语言学生记录程序中融入指针并实现文件存储?

学生记录管理程序:指针优化与文件存储实现

你的原代码其实已经在使用指针了——比如getscore函数的char *name、int *grade1这些参数都是指针,用来接收主函数中数组元素的地址,从而修改对应的值。不过我们可以进一步用结构体+指针更系统地应用指针,同时实现文件存储功能,满足教授的要求。

原代码的小问题修正

  • average函数中(a+b+c)/3是整数除法,会导致平均分计算错误(比如80+80+81=241,整数除法结果为80,实际应为80.33),需要强制转换为浮点数计算。
  • rate函数的条件错误:ave > 91、ave >94、ave>97、ave>99应改为>=,否则对应分数会被错误归类为5.00。
  • getch()需要包含<conio.h>头文件,换成更通用的system("pause")兼容性更好。

结构体+指针重构代码(含文件功能)

我们定义Student结构体统一存储单个学生的所有数据,用指针操作结构体数组,同时添加文件读写函数实现记录持久化。

修改后的完整代码

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

#define MAX_STUDENTS 3

// 定义学生结构体,整合所有数据
typedef struct {
    char name[50];
    int quiz1;
    int quiz2;
    int quiz3;
    float average;
    float rating;
} Student;

// 函数声明
void getStudentData(Student *student);
float calculateAverage(int a, int b, int c);
float getRating(float ave);
void displayStudents(Student *students, int count);
void saveToFile(Student *students, int count);
void loadFromFile(Student *students, int *count);

int main() {
    Student students[MAX_STUDENTS];
    int i;
    int studentCount = MAX_STUDENTS;

    system("cls");
    for (i = 0; i < MAX_STUDENTS; i++) {
        system("cls");
        printf("\t\tInput Student Record\n");
        printf("Student# %d\n", i + 1);
        getStudentData(&students[i]);  // 传递结构体元素的地址(指针)
        students[i].average = calculateAverage(students[i].quiz1, students[i].quiz2, students[i].quiz3);
        students[i].rating = getRating(students[i].average);
    }

    displayStudents(students, studentCount);
    saveToFile(students, studentCount);
    printf("\n\n数据已保存到student_records.txt\n");

    // 可选:从文件读取数据并验证
    Student loadedStudents[MAX_STUDENTS];
    int loadedCount;
    loadFromFile(loadedStudents, &loadedCount);
    printf("\n\n从文件读取的记录:\n");
    displayStudents(loadedStudents, loadedCount);

    system("pause");
    return 0;
}

// 用结构体指针直接修改学生数据
void getStudentData(Student *student) {
    printf("Student Name: ");
    scanf("%s", student->name);  // 指针访问结构体成员用->

    printf("Quiz Score#1: ");
    scanf("%d", &student->quiz1);  // 基本类型成员需取地址

    printf("Quiz Score#2: ");
    scanf("%d", &student->quiz2);

    printf("Quiz Score#3: ");
    scanf("%d", &student->quiz3);
}

float calculateAverage(int a, int b, int c) {
    return (float)(a + b + c) / 3;  // 强制转换为浮点数避免整数除法误差
}

float getRating(float ave) {
    if (ave >= 99 && ave <= 100)
        return 1.00;
    else if (ave >= 97 && ave <= 98)
        return 1.25;
    else if (ave >= 94 && ave <= 96)
        return 1.50;
    else if (ave >= 91 && ave <= 93)
        return 1.75;
    else if (ave >= 88 && ave <= 90)
        return 2.00;
    else if (ave >= 84 && ave <= 87)
        return 2.25;
    else if (ave >= 80 && ave <= 83)
        return 2.50;
    else if (ave >= 77 && ave <= 79)
        return 2.75;
    else if (ave >= 75 && ave <= 76)
        return 3.00;
    else
        return 5.00;
}

// 用指针遍历结构体数组,批量显示数据
void displayStudents(Student *students, int count) {
    int i;
    printf("\nStudent Grade Record\n");
    printf("\nNo. Name\tQuiz_1\tQuiz_2\tQuiz_3\tAverage\tRating\n");
    for (i = 0; i < count; i++) {
        printf("%d.) %s\t\t%d\t%d\t%d\t%.2f\t%.2f\n", 
               i+1, students[i].name, students[i].quiz1,
               students[i].quiz2, students[i].quiz3, students[i].average, students[i].rating);
    }
}

// 将学生数据写入文件
void saveToFile(Student *students, int count) {
    FILE *file = fopen("student_records.txt", "w");
    if (!file) {
        printf("无法打开文件!\n");
        return;
    }
    for (int i = 0; i < count; i++) {
        fprintf(file, "%s %d %d %d %.2f %.2f\n", 
                students[i].name, students[i].quiz1,
                students[i].quiz2, students[i].quiz3, students[i].average, students[i].rating);
    }
    fclose(file);
}

// 从文件读取学生数据
void loadFromFile(Student *students, int *count) {
    FILE *file = fopen("student_records.txt", "r");
    if (!file) {
        printf("无法打开文件!\n");
        *count = 0;
        return;
    }
    *count = 0;
    while (fscanf(file, "%s %d %d %d %f %f", 
                 students[*count].name, &students[*count].quiz1,
                 &students[*count].quiz2, &students[*count].quiz3,
                 &students[*count].average, &students[*count].rating) != EOF) {
        (*count)++;
        if (*count >= MAX_STUDENTS) break;
    }
    fclose(file);
}

关键指针应用说明

  1. 结构体指针:getStudentData(Student *student)接收结构体地址,通过student->name直接修改主函数中结构体数组的元素,避免值传递的冗余。
  2. 数组指针:displayStudents(Student *students, int count)中,students是结构体数组的指针,students[i]等价于*(students+i),通过指针遍历数组。
  3. 文件指针:FILE *file是文件操作的核心指针,用来控制文件的打开、读写和关闭。

内容的提问来源于stack exchange,提问作者Tharanee Benlot

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 21:36:08