代码不能接受超出数组大小的文件?

时间:2016-11-02 19:02:57

标签: c++ arrays file filestream stringstream

下面我有我正在处理的项目的当前代码。这是为了获取学生及其成绩的文件,平均成绩,然后将它们全部放回输出文件中。学生人数不应超过10人,因此,如果学生人数超过10人,则应仅阅读前10名学生,然后撤销订单。当给出一个包含10个以上学生的文件时,我的代码完全可以解决这个问题。它似乎正在尝试访问内存中不存在的部分。我试着让代码忽略空行,它应该,但似乎没有解决它。我的“阅读”功能是我认为问题所在。

#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;
    }
}

1 个答案:

答案 0 :(得分:0)

在我看来,找到空行后你应该尝试使用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++;
    }
}