代码无法接受超过数组大小的文件?

Code can't accept file that exceeds array size?

本文关键字:文件 数组 代码      更新时间:2023-10-16

下面是我目前正在进行的一个项目的代码。它的意思是把学生和他们的成绩的文件,平均成绩,然后把它们都放回一个输出文件。学生的数量不应该超过10个,所以如果有超过10个学生,它应该只读取前10个,然后颠倒顺序。我的代码工作完美,除了给一个文件超过10个学生。它似乎在试图访问内存中不存在的部分。我试着让代码忽略空行,它应该,但这似乎并没有解决它。我的"read"函数是我认为问题所在。

#include <iostream>
#include <fstream>
#include <sstream>
#include <iomanip>
using namespace std;
//My student structure that holds the variable for each student object.
struct Student
{
    string fname;
    string lname;
    double average;
};
//Prototyping the functions to read the input file into an array and then reverse it.
int read(ifstream &fin, Student s[]);
void print(ofstream &fout, Student s[], int amount);
void reverse(Student s[], int amount);
int main()
{
    //Creating the file streams and global constant for the array and the filling it with I/O.
    const int size = 10;
    ifstream fin;
    ofstream fout;
    string inputFile;
    string outputFile;
    Student s[size];
    cout << "Enter input filename: ";
    cin >> inputFile;
    cout << "Enter output filename: ";
    cin >> outputFile;
    //opeining the files given by the user and then testing if the opened.
    fin.open(inputFile.c_str());
    fout.open(outputFile.c_str());
    if(fin.fail()) {
        cout << "Unable to open input file.n";
        return 1;
    }

    //calling my 3 functions and then returning to main(). Closing files as well.
    int count = read(fin , s);
    reverse(s, count);
    print(fout, s, count);
    count = 0;
    fin.close();
    fout.close();
}
//This function reads the file given and breaks it up using string stream. It then calculates the averages for each stuent and assigns it to the array.
int read(ifstream &fin, Student s[])
{
    istringstream sin;
    string line;
    string firstName;
    string lastName;
    double score;
    double total;
    double i=0;
    int totalStudents=0;
    Student stu;
    for(int j = 0; j < 10; j++){
    while(getline(fin, line)){
        sin.clear();
        if(line.empty())
        {
            j--;
        }else{
            sin.str(line);
        while(sin >> firstName >> lastName){
            stu.fname = firstName;
            stu.lname = lastName;
            while(sin >> score){
            total += score;
            i++;
            stu.average = (total/i);
            }
        }
        s[totalStudents]=stu;
        totalStudents++;
        stu.average = 0;
        total = 0;
        i = 0;
    }
    }
    }
    //returning the number of students in the file so it can later be used for the variable of total students.
    return totalStudents;
}
//My print function that puts the array into a given output file.
void print(ofstream &fout, Student s[], int amount)
{
    for(int i = 0; i<amount; i++)
    {
        if(s[i].lname.empty())
        {
            fout<<"No students to report.";
        }else{
        ostringstream sout;
        sout << s[i].lname.c_str() << ", " << s[i].fname.c_str();
        fout <<setw(21)<< left << sout.str() << setprecision(2) << fixed << "= " << s[i].average << 'n';
    }
    }
}
//the function that reverses the order of the students by copying the last student into a temporary variable and casting it to the beggining.
void reverse(Student s[], int amount)
{
    Student temp;
    for(int i=0; i< amount/2; i++)
    {
        temp=s[i];
        s[i]=s[amount-i-1];
        s[amount - i - 1] = temp;
    }
}

在我看来,找到空行后,你应该尝试使用continue语句,而不是:

for (int j = 0; j < 10; j++) {
    while (getline(fin, line)) {
        sin.clear();
        if (line.empty())
        {
            continue;
        }
        else {
            sin.str(line);
            while (sin >> firstName >> lastName) {
                stu.fname = firstName;
                stu.lname = lastName;
                while (sin >> score) {
                    total += score;
                    i++;
                    stu.average = (total / i);
                }
            }
            s[j] = stu;
            stu.average = 0;
            total = 0;
            i = 0;
        }
    }
}

根据注释,我错过了for循环。它可以完全消除,只使用while循环和计数器:

int j = 0;
while (getline(fin, line) && j < 10)
{
    sin.clear();
    if (line.empty())
    {
        continue;
    }
    else
    {
        sin.str(line);
        while (sin >> firstName >> lastName)
        {
            stu.fname = firstName;
            stu.lname = lastName;
            while (sin >> score)
            {
                total += score;
                i++;
                stu.average = (total / i);
            }
        }
        s[j] = stu;
        stu.average = 0;
        total = 0;
        i = 0;
        j++;
    }
}