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

C++解析CSV文件显示异常及GPA计算实现技术问询

CSV解析异常原因及GPA计算实现方案

一、CSV解析异常的原因及修复

问题根源

你的代码在读取完RollNumbers后,输入流中残留了逗号分隔符,后续直接用>>读取数值时,因逗号不是有效数字导致读取失败,未初始化的变量会显示随机垃圾值(如0、212、负数等)。此外,CSV前两行的表头和总分说明被当作学生数据读入,也会产生无效输出。

修复后的完整代码

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <iomanip>
using namespace std;

struct StudentRecord{
    string StudentNames;
    int RollNumbers;
    int Mid;
    int Final;
    int Project;

    StudentRecord(string name, int roll, int mid, int final, int project)
        : StudentNames(name), RollNumbers(roll), Mid(mid), Final(final), Project(project) {}

    void displayInfo(){
        cout << "学生姓名: " << StudentNames << endl;
        cout << "学号: " << RollNumbers << endl;
        cout << "期中成绩: " << Mid << endl;
        cout << "期末成绩: " << Final << endl;
        cout << "项目成绩: " << Project << endl;
        cout << "-------------------------" << endl;
    }

    double calculateGPA(double midWeight, double finalWeight, double projectWeight) {
        // 将成绩转换为百分制占比
        double midPercent = static_cast<double>(Mid) / 100;
        double finalPercent = static_cast<double>(Final) / 100;
        double projectPercent = static_cast<double>(Project) / 40;

        // 加权计算总分后转换为4分制GPA
        double totalScore = midPercent * midWeight + finalPercent * finalWeight + projectPercent * projectWeight;
        return (totalScore / 100) * 4.0;
    }
};

void displayStudents(vector<StudentRecord>& students){
    for(auto& student : students){
        student.displayInfo();
    }
}

void displayStudentsWithGPA(vector<StudentRecord>& students, double midW, double finalW, double projectW) {
    cout << fixed << setprecision(2);
    for(auto& student : students){
        student.displayInfo();
        double gpa = student.calculateGPA(midW, finalW, projectW);
        cout << "GPA: " << gpa << endl;
        cout << "-------------------------" << endl;
    }
}

int main(){
    ifstream inputFile("C:\\Users\\hasan\\Desktop\\file_handling project\\NCA.csv");
    if(!inputFile.is_open()){
        cout << "无法打开文件!" << endl;
        return 1;
    }

    string line;
    vector<StudentRecord> students;

    // 跳过表头和总分说明行
    getline(inputFile, line);
    getline(inputFile, line);

    while(getline(inputFile, line)){
        stringstream inputString(line);

        string name, rollStr, midStr, finalStr, projectStr;

        // 按逗号分割所有字段
        getline(inputString, name, ',');
        getline(inputString, rollStr, ',');
        getline(inputString, midStr, ',');
        getline(inputString, finalStr, ',');
        getline(inputString, projectStr, '\n');

        // 字符串转整数,自动忽略首尾空格
        int roll = stoi(rollStr);
        int mid = stoi(midStr);
        int final = stoi(finalStr);
        int project = stoi(projectStr);

        students.emplace_back(name, roll, mid, final, project);
    }

    cout << "=== 学生成绩数据 ===" << endl;
    displayStudents(students);

    // 接收权重输入并计算GPA
    double midWeight, finalWeight, projectWeight;
    cout << "\n请输入各成绩权重(期中、期末、项目,总和建议为100):" << endl;
    cout << "期中权重: ";
    cin >> midWeight;
    cout << "期末权重: ";
    cin >> finalWeight;
    cout << "项目权重: ";
    cin >> projectWeight;

    cout << "\n=== 学生GPA结果 ===" << endl;
    displayStudentsWithGPA(students, midWeight, finalWeight, projectWeight);

    inputFile.close();
    return 0;
}

修复核心要点

  • 统一字段分割方式:全程用getline(..., ',')分割所有字段,避免>>操作残留分隔符的问题,再通过stoi完成字符串到整数的转换,自动处理字段前后的空格。
  • 过滤无效行:用两次getline跳过CSV的表头行和总分说明行,避免无效数据被读入。
  • 优化构造函数:改用成员初始化列表,提升代码效率与规范性。

二、GPA计算实现思路

  1. 权重输入:从终端接收用户输入的期中、期末、项目成绩权重(如30、50、20,总和建议为100)。
  2. 成绩归一化:因项目总分是40,需先将项目成绩转换为百分制占比(项目成绩/40),期中、期末成绩直接用成绩/100转换。
  3. 加权计算:通过(期中占比×期中权重)+(期末占比×期末权重)+(项目占比×项目权重)得到加权总分(0-100),再转换为4分制GPA(总分/100×4)。
  4. 模块化设计:将GPA计算方法集成到StudentRecord结构体中,每个学生对象可直接调用计算自身GPA。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 08:15:56