成绩信息统计:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string>
#include<vector>
using namespace std;
class students
{
    string id;
    string name;
    vector<string>kechengming;
    vector<double>score;
    vector<double>xuefen;
    public:          //计算总分,平均绩点的函数
    double sum1()
    {
        double sum=0;
        for(int i=0;i<score.size();i++)
        sum+=score[i];
        return sum;
    };
    double jidian1()
    {
        double jidianhe=0;
        double xuefenhe=0;
        double gpa;
        for(int i=0;i<score.size();i++)
        {
            if(score[i]<60)
            xuefen[i]=0;
            else
            jidianhe+=(score[i]-50)/10*xuefen[i];
        }
        for(int i=0;i<score.size();i++)
        {
            xuefenhe+=xuefen[i];
        }
        gpa=jidianhe/xuefenhe;
        return gpa;
    };
    string getid()                     //读取学生信息:学号,姓名,课程名,该科目成绩等
    {
        return id;
    }
    string getname()
    {
        return name;
    }
    string getkechengming(int i)
    {
        return kechengming[i];
    }
    double getscore(int i)
    {
        return  score[i];
    }
    int getsize()
    {
        return score.size();
    }
    void setid(string a)              //修改(写入)学生信息:学号,姓名,课程名,该科目成绩,该科目学分等
    {
         id=a;
    }
    void setname(string a)
    {
         name=a;
    }
    void setkechengming(string a)
    {
        kechengming.push_back(a);
    }
    void setscore(double a)
    {
        score.push_back(a);
    }
    void setxuefen(double a)
    {
        xuefen.push_back(a);
    }
};

bool cmp(students a,students b)
{
    return a.jidian1()>b.jidian1();
}

int main()
{
    printf("首先输入测试学生数n,然后依次输入每个同学的信息:\n");
    printf("学号,姓名,该生报考科目(每个学生的选课情况不一)(这里全部使用动态数组进行取存),该科成绩,该科学分。\n");
    printf("当输入考试科目为零时,表示该生信息读取完毕,接着读取下一位同学信息。\n");
    int n;                       //表示学生人数
    cin>>n;
    students a[n];
    for(int i=0;i<n;i++)
    {
        string id;               //初始化学生信息:包括学号,姓名,课程名,该科成绩,该科学分等
        string name;
        string kechengming;
        cin>>id>>name;
        a[i].setid(id);
        a[i].setname(name);
        while(cin>>kechengming)
        {
            if(kechengming=="0")            //初始化过程中当输入下一科课程名为零时表示当前学生信息读取完毕,然后初始化下一位学生的学生信息
                break;
            double score;
            double xuefen;
            cin>>score>>xuefen;
            a[i].setkechengming(kechengming);
            a[i].setscore(score);
            a[i].setxuefen(xuefen);
        }
    }
    sort(a,a+n,cmp);
    for(int i=0;i<n;i++)                                     //输出学生成绩信息
    {
        cout<<a[i].getid()<<"\t"<<a[i].getname()<<"\t";
        for(int j=0;j<a[i].getsize();j++)
        {
            cout<<a[i].getkechengming(j)<<"\t"<<a[i].getscore(j)<<"\t";
        }
        cout<<a[i].sum1()<<"\t"<<a[i].jidian1()<<endl;
    }
    return 0;
}

该代码以访问器和修改器的方式来读取修改数据,比直接读取数据更能体现类的思想,封装的原理,安全性相对直接读取修改数据来说较高。
当然当需要写入的数据量过大时(如测试数据二)也可以采取文件读入的方式来写入数据(代码二用的文件操作进行写入,可进行部分参考。)

这两组测试数据的选修科目都要写入(因为选修课程可能不一)
另外在数据输出时可能会有汉字乱码问题(如数据二),因为用的cout,printf等直接输出汉字类型的字符串可能会导致乱码错误。
这也与编译环境有关(我的电脑没事,正常编译(可能是兼容性好一点)舍友的电脑有的就不行(这种问题在第一次进行成绩统计的时候就存在)
当时在输出时我将其全部转换为C风格的字符串(就可以正常输出不乱码了)
这可以参考代码三。

测试数据如下:

数据一:

2
2018 xiaoming gaoshu 100 5 yihngyu 100 3 0
2019 xiaohong gaoshu 90 5 yingyu 90 3 C++ 90 3 0

数据二:

这是宿舍八个人的数据(数据的学号,姓名有所删改)(按床号来分为葫芦兄弟)

8
2018001 大娃 导论 91 1.5 导论实验 95 0.5 程序设计 63 2 设计实验 85 1 生涯规划 90 0.5 高数 46 5 思修 95 2 马克思 69 3 体育 89 1 英语 56 2 认识实习 95 1 军事理论 96 1 0
2018002 二娃 导论 87 1.5 导论实验 95 0.5 程序设计 77 2 设计实验 85 1 生涯规划 85 0.5 高数 78 5 思修 97 2 马克思 84 3 体育 100 1 英语 62 2 认识实习 85 1 军事理论 90 1 0
2018003 三娃 导论 85 1.5 导论实验 85 0.5 程序设计 80 2 设计实验 95 1 生涯规划 94 0.5 高数 71 5 思修 93 2 马克思 80 3 体育 87 1 英语 64 2 认识实习 95 1 军事理论 98 1 0
2018004 四娃 导论 94 1.5 导论实验 95 0.5 程序设计 82 2 设计实验 95 1 生涯规划 88 0.5 高数 76 5 思修 95 2 马克思 81 3 体育 94 1 英语 69 2 认识实习 95 1 军事理论 97 1 0
2018005 五娃 导论 95 1.5 导论实验 95 0.5 程序设计 84 2 设计实验 95 1 生涯规划 97 0.5 高数 85 5 思修 93 2 马克思 78 3 体育 90 1 英语 76 2 认识实习 95 1 军事理论 91 1 0
2018006 六娃 导论 97 1.5 导论实验 95 0.5 程序设计 83 2 设计实验 95 1 生涯规划 88 0.5 高数 94 5 思修 93 2 马克思 85 3 体育 92 1 英语 72 2 认识实习 95 1 军事理论 92 1 0
2018007 七娃 导论 86 1.5 导论实验 95 0.5 程序设计 50 2 设计实验 75 1 生涯规划 85 0.5 高数 42 5 思修 83 2 马克思 74 3 体育 85 1 英语 85 2 认识实习 75 1 军事理论 97 1 0
2018008 小金刚 导论 89 1.5 导论实验 95 0.5 程序设计 82 2 设计实验 95 1 生涯规划 85 0.5 高数 94 5 思修 91 2 马克思 86 3 体育 90 1 英语 79 2 认识实习 95 1 军事理论 91 1 0

代码二:
这里规定是对30组数据进行操作(科目固定统一)(最后写上总学分以计算平均学分绩点(考虑到挂科情况))
从文件名为"txt"的".txt"文本中读取数据(需要先建立该文本文件),并将结果写到名为"output"的文本文件中

#include<bits/stdc++.h>
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
struct student
{
    string name;
    float gs,yy,sx,dl,cx,sy,ty,mk,js,cxsy,jdsy,rssx;
    float total,jd,xf;
}n[100];
bool cmp(student a,student b)
{return a.jd>b.jd;}
using namespace std;
int main()
{
    ifstream in("txt.txt");
    //cout<<"姓名"<<"\t"<<"学号"<<" "<<"计算机导论"<<" "<<"程序设计"<<" "<<"生涯规划"<<" "<<"高数"<<" "<<"思修"<<" "<<"马原"<<" "<<"体育"<<" "<<"英语"<<" "<<"军事理论"<<" "<<"学分"<<endl;
	    for(int i=0;i<30;i++)
        {
            in>>n[i].name>>n[i].dl>>n[i].jdsy>>n[i].cx>>n[i].cxsy>>n[i].sy>>n[i].gs>>n[i].sx>>n[i].mk>>n[i].ty>>n[i].yy>>n[i].rssx>>n[i].js>>n[i].xf;
            //if(n[i].dl<60) n[i].dl=50;if(n[i].cx<60) n[i].cx=50;if(n[i].sy<60) n[i].sy=50;
            //if(n[i].gs<60) n[i].gs=50;if(n[i].sx<60) n[i].sx=50;if(n[i].mk<60) n[i].mk=50;
            //if(n[i].ty<60) n[i].ty=50;if(n[i].yy<60) n[i].yy=50;if(n[i].js<60) n[i].js=50;
            n[i].total=n[i].dl+n[i].cx+n[i].sy+n[i].gs+n[i].sx+n[i].mk+n[i].ty+n[i].yy+n[i].js;
            n[i].jd=((n[i].dl/10-5)*1.5+(n[i].cx/10-5)*2+(n[i].sy/10-5)*0.5+(n[i].gs/10-5)*5+(n[i].sx/10-5)*2+(n[i].mk/10-5)*3+(n[i].ty/10-5)*1+(n[i].yy/10-5)*2+(n[i].js/10-5)*1+n[i].cxsy*1+n[i].jdsy*0.5+n[i].rssx*1)/n[i].xf;
        }
	in.close();
	ofstream out;
    sort(n,n+30,cmp);
    cout<<endl;
    out.open("output.txt");
    //out<<"姓名"<<"\t"<<"学号"<<" "<<"计算机导论"<<" "<<"程序设计"<<" "<<"生涯规划"<<" "<<"高数"<<" "<<"思修"<<" "<<"马原"<<" "<<"体育"<<" "<<"英语"<<" "<<"军事理论"<<" "<<"绩点";
    for(int i=0;i<30;i++)
    out<<n[i].name<<"\t"<<n[i].dl<<" "<<n[i].jdsy<<" "<<n[i].cx<<" "<<n[i].cxsy<<" "<<n[i].sy<<" "<<n[i].gs<<" "<<n[i].sx<<" "<<n[i].mk<<" "<<n[i].ty<<" "<<n[i].yy<<" "<<n[i].rssx<<" "<<n[i].js<<" "<<n[i].total<<" "<<n[i].jd<<endl;
    out.close();
    return 0;
  }

测试数据("txt"文件中应存放的数据):(号码仅代表顺序,与成绩顺序无关(本是人名)(隐藏了))

1号	98	4.5	84	4.5	93	91	91	77	89	78	4.5	95  20.5
2号	92	4.5	91	4.5	98	85	99	78	89	76	4.5	96	20.5
3号	90	4.5	80	4.5	94	86	96	88	92	74	4.5	91 	20.5
4号	86	3.5	83	4.5	96	93	92	81	89	72	3.5	92 	20.5
5号	95	4.5	82	4.5	96	79	95	79	91	76	4.5	90  20.5
6号	94	4.5	82	4.5	88	76	95	81	94	69	4.5	97 20.5
7号	95	4.5	78	3.5	94	85	86	81	88	68	4.5	97	20.5
8号	95	4.5	84	4.5	97	85	93	78	90	76	4.5	91	20.5
9号	91	4.5	63	3.5	90	46	95	69	89	56	4.5	96 20.5
10号	95	4.5	93	4.5	96	76	86	73	91	51	4.5	97	20.5
11号	90	3.5	64	3.5	96	91	86	80	83	81	4.5	95 20.5
12号	95	4.5	92	4.5	96	70	94	86	90	73	4.5	93 20.5
13号	87	4.5	77	3.5	85	78	97	84	100	62	3.5	90	20.5
14号	87	3.5	73	3.5	96	78	87	79	95	72	4.5	98 20.5
15号	96	4.5	81	4.5	98	90	95	88	91	88	4.5	97 	 20.5
16号	97	4.5	83	4.5	88	94	93	85	92	72	4.5	92 	20.5
17号	89	4.5	82	4.5	85	94	91	86	90	79	4.5	91 	20.5
18号	93	4.5	80	4.5	95	73	91	78	81	68	4.5	98	20.5
19号	95	4.5	69	3.5	86	48	88	73	92	67	4.5	97	20.5
20号	93	4.5	55	3.5	96	62	94	87	91	68	4.5	98	20.5
21号	85	3.5	80	4.5	94	71	93	80	87	64	4.5	98 	20.5
22号	89	3.5	50	2.5	71	74	95	78	81	72	4.5	98 20.5
23号	90	4.5	64	3.5	97	68	96	84	92	69	4.5	93  20.5
24号	94	4.5	73	3.5	95	63	97	76	98	63	4.5	91 20.5
25号	93	4.5	73	3.5	96	63	92	75	95	65	4.5	98 20.5
26号	80	3.5	44	2.5	95	68	94	70	90	72	4.5	96 	20.5
27号	94	4.5	82	4.5	96	60	97	77	92	53	4.5	98 	20.5
28号	96	4.5	86	4.5	95	65	96	74	89	55	3.5	92 	20.5
29号	89	4.5	86	4.5	95	60	83	74	89	62	3.5	90 	20.5
30号	86	4.5	50	2.5	85	42	83	74	85	85	2.5	97 20.5

代码三:

n组测试数据(科目固定统一)
输出时将其全部转换为C风格的字符串(就可以正常输出不乱码了)

#include <iostream>
#include<cstdio>
#include<string>
#include <algorithm>
#include<cmath>
using namespace std;
struct X
	{
		string name;
		int xuehao;
		double gaoshu;
		double yingyu;
		double daolun;
		double chengxu;
		double daolunshiyan;
		double chengxushiyan;
		double shengya;
		double sixiu;
		double makesi;
		double junshililun;
		double tiyu;
		double renshishixi;
		int sum;
		double jidian;
	};
	int cmp(X a,X b)
	{
	    return a.jidian>b.jidian;
	}
int main()
{
    printf("请输入总人数:\n");
	int n;
	cin>>n;
	printf("请依次输入:学号  姓名  计算机导论  导论实验  程序设计  程序设计实验  大学生涯规划  高数  思修  马克思  体育  英语  认识实习  军事理论");
	cout<<"(注:优秀为95分,良好为85分,及格为75分)"<<endl;
	X stu[n];
	for(int i=0;i<n;i++)
	{
		cin>>stu[i].xuehao>>stu[i].name>>stu[i].daolun>>stu[i].daolunshiyan>>stu[i].chengxu>>stu[i].chengxushiyan>>stu[i].shengya>>stu[i].gaoshu>>stu[i].sixiu>>stu[i].makesi>>stu[i].tiyu>>stu[i].yingyu>>stu[i].renshishixi>>stu[i].junshililun;
		stu[i].sum=stu[i].daolun+stu[i].daolunshiyan+stu[i].chengxu+stu[i].chengxushiyan+stu[i].shengya+stu[i].gaoshu+stu[i].sixiu+stu[i].makesi+stu[i].tiyu+stu[i].yingyu+stu[i].renshishixi+stu[i].junshililun;
		stu[i].jidian=((stu[i].daolun-50)/10*1.5+(stu[i].daolunshiyan-50)/10*0.5+(stu[i].chengxu-50)/10*2+(stu[i].chengxushiyan-50)/10+(stu[i].shengya-50)/10*0.5+(stu[i].gaoshu-50)/10*5+(stu[i].sixiu-50)/10*2+(stu[i].makesi-50)/10*3+(stu[i].tiyu-50)/10+(stu[i].yingyu-50)/10*2+(stu[i].renshishixi-50)/10+(stu[i].junshililun-50)/10)/20.5;
	}
	/*for(int i=0;i<n;i++)
	for(int j=0;j<n-i-1;j++)
	{
		if(stu[j].jidian<stu[j+1].jidian)
		swap(stu[j],stu[j+1]);
	*(这里本来有个/)
	sort(stu,stu+n,cmp);
	printf("学号\t\t姓名\t\t计算机导论\t导论实验\t程序设计\t程序设计实验\t大学生涯规划\t高数\t思修\t马克思\t体育\t英语\t认识实习\t军事理论\t绩点\n");
	for(int i=0;i<n;i++)
	{
		cout<<stu[i].xuehao<<"\t";
		printf(stu[i].name.c_str());//s.c_str();转换,返回s中内容对应的C风格字符串首地址。
		cout<<"\t"<<"\t"<<stu[i].daolun<<"\t"<<"\t"<<stu[i].daolunshiyan<<"\t"<<"\t"<<stu[i].chengxu<<"\t"<<"\t"<<stu[i].chengxushiyan<<"\t"<<"\t"<<stu[i].shengya<<"\t"<<"\t"<<stu[i].gaoshu<<"\t"<<stu[i].sixiu<<"\t"<<stu[i].makesi<<"\t"<<stu[i].tiyu<<"\t"<<stu[i].yingyu<<"\t"<<stu[i].renshishixi<<"\t"<<"\t"<<stu[i].junshililun<<"\t"<<"\t";
		printf("%.3lf",stu[i].jidian);
        cout<<endl;
	}
	return 0;
}

测试数据:

2018216488 大娃 91 95 63 85 90 46 95 69 89 56 95 96
2018212584 二娃 87 95 77 85 85 78 97 84 100 62 85 90
2018212591 三娃 85 85 80 95 94 71 93 80 87 64 95 98
2018212555 四娃 94 95 82 95 88 76 95 81 94 69 95 97
2018212598 五娃 95 95 84 95 97 85 93 78 90 76 95 91
2018212543 六娃 97 95 83 95 88 94 93 85 92 72 95 92
2018212942 七娃 86 95 50 75 85 42 83 74 85 85 75 97
2018212551 小金刚 89 95 82 95 85 94 91 86 90 79 95 91