首页 > 解决方案 > C++ 结构和数组:打印所有数组值的问题

问题描述

我将把程序要求放在下面。我是新手,所以我真诚地感谢尽可能多的解释来帮助我学习。就目前而言,我的 pass.txt 文件和我的 fail.txt 文件都只显示来自最后一个已知用户输入的信息(每个文本文件只显示一个学生)。我猜我的数组不断被覆盖?我应该如何解决这个问题?

该程序输出将产生两个输出文本文件。编写一个程序,提示用户输入 5 个学生的以下数据:学生姓名、学生 ID、考试 1 成绩、考试 2 成绩、期末考试成绩、实验成绩和作业成绩。

每个学生的最终学期成绩计算如下: • 15% - 考试 1 成绩 • 15% - 考试 2 成绩 • 20% - 期末考试成绩 • 40% - 实验成绩 • 10% - 家庭作业成绩

计算出最终学期成绩后,程序应调用函数 giveBonus( ) 以在原始分数的基础上给每个学生 3 分。但是,新的期末成绩不能超过 100。如果高于 100,函数必须将新的分数更改为 100。

将所有通过考试的学生的姓名、ID和成绩保存在“pass.txt”文件中。还将未通过测试的学生的姓名、ID 和成绩保存在“fail.txt”文件中。及格分数为60。

#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>

using namespace std;

struct students
    //Students structure created to hold the following data for 5 students: student name, student ID, exam-1 grade, exam-2 grade, final exam grade, lab grade and homework grade.
{
    string name; //student's name 
    int ID{}; //student's ID 
    double exam1{}, exam2{}, final{}, lab{}, homework{}, avg{}; 
};

void getDetails(students& student)
//user input to retrieve student name, student ID, exam-1 grade, exam-2 grade, final exam grade, lab grade and homework grades for the 5 total students
{
    cout << "Enter student name: ";
    cin >> student.name;

    cout << "Enter student ID: ";
    cin >> student.ID;

    cout << "Enter their grade for the first exam: ";
    cin >> student.exam1;

    cout << "Enter their grade for the second exam: ";
    cin >> student.exam2;

    cout << "Enter their grade for the final exam: ";
    cin >> student.final;

    cout << "Enter their lab grade: ";
    cin >> student.lab;

    cout << "Enter their homework grade: ";
    cin >> student.homework;

    cout << "\n";

}

double calculateFinalGrade(students& student)
//calculate the preliminary final semester grade for each individual student
{
    double avg;

    avg = ((student.exam1 * .15) + (student.exam2 * .15) + (student.final * .20) + (student.lab * .40) + (student.homework * .10));

    return avg;
}

double giveBonus(students& student)
//function to give students an additional 3 pts added to their final grade; however, students cannot exceed 100 total points
{
    student.avg += 3;
    if (student.avg > 100)
    {
        student.avg = 100;
    }
    return student.avg;
}

void print(students& student)
//output student data to one of two text files based on their final avg
{
    ofstream outPass; //output pass.txt file stream variable 
    ofstream outFail; //output fail.txt file stream variable 

    if (student.avg >= 60) //if the student's average is GREATER than or equal to 60, then output is directed to "pass.txt" file
    {
        //create and open text file for students whose avg is GREATER than 60
        outPass.open("pass.txt", ios::out); //creating pass text file to house student info
        outPass << fixed << showpoint;
        outPass << setprecision(2); //set precision to 2 decimal places for grades

        outPass << "Student Name" << setw(15) << "Student ID" << setw(13) << "Exam 1" << setw(14) << "Exam 2" << setw(18) << "Final Exam" << setw(16)
            << "Lab Grade" << setw(20) << "Homework Grade" << setw(20) << "Adjusted Average" << endl;

        //passing these values to "pass.txt" file
        outPass << student.name << setw(19) << student.ID << setw(16) << student.exam1 << setw(14) << student.exam2 << setw(16) << student.final << setw(17)
            << student.lab << setw(18) << student.homework << setw(17) << student.avg << endl;
    }
    else //if the student's average is LESS THAN 60, then output is directed to "fail.txt" file
    {
        //create and open text file for students whose avg is less than 60
        outFail.open("fail.txt", ios::out); //creating output fail file to house student info 
        outFail << fixed << showpoint;
        outFail << setprecision(2); //set precision to 2 decimal places for grades

        outFail << "Student Name" << setw(15) << "Student ID" << setw(13) << "Exam 1" << setw(14) << "Exam 2" << setw(18) << "Final Exam" << setw(16)
            << "Lab Grade" << setw(20) << "Homework Grade" << setw(20) << "Adjusted Average" << endl;

        //passing these values to "fail.txt" file
        outFail << student.name << setw(19) << student.ID << setw(16) << student.exam1 << setw(14) << student.exam2 << setw(16) << student.final << setw(17)
            << student.lab << setw(18) << student.homework << setw(17) << student.avg << endl;
    }
    outPass.close(); //closing "pass.txt" file
    outFail.close(); //closing "fail.txt" file
}

int main()
{
    students studentArray[5]; //array to hold the student's data 
    
    for (int i = 0; i < 5; i++) //iterate through the 5 total students
    {
        cout << "Enter details for student " << (i + 1) << endl;

        getDetails(studentArray[i]); //get information relating to each of the 5 students

        studentArray[i].avg = calculateFinalGrade(studentArray[i]); //calculate the final grade 

        studentArray[i].avg = giveBonus(studentArray[i]); //assign additional 3 bonus points, if necessary
    }

    for (int i = 0; i < 5; i++)
    {
        print(studentArray[i]);
    }

    return 0;
}

标签: c++arraystext-filesstructureuser-input

解决方案


每次打开通过或失败文件时,都会覆盖它。

任何一个:

  • 停止为每个学生打开通过和/或失败的文件

    (相反,您可以打开两个文件一次,并将它们传递给您错误命名的“打印”函数)

    或者

  • 使用附加标志打开通过和失败文件ios::app

这些标志的使用在文档中进行了描述std::basic_filebuf::open- 请注意,如果文件已存在,则操作列明确表示仅使用out您当前正在执行的标志打开:

销毁内容

这就是它正在做的事情。


推荐阅读