C++ 中的文件和 std::array

问题描述 投票:0回答:1

我必须使用包含不同数量数字的各种文件并计算某些总数。我的代码遇到的唯一问题是,当我从文件中读取并将数字传递到数组中时,文件中的最后一个数字在它应该结束时被重复接受到数组中。请帮助解决这个问题,我不明白为什么它到达文件末尾后就不会停止。

我的代码如下:

#include <iostream>
#include <fstream>
#include <iomanip>
#include <array>

const int kMaxSize {30};

std::array < int, kMaxSize > ProcessFile(std::ifstream &infile, int &num_grades);
double CalculateFinalGrade(std::array < int, kMaxSize > grades, int &num_grades);
int CalculateTotal(std::array < int, kMaxSize > grades, int &num_grades);
char CalculateLetter(double final_grade);

int main(){

    std::string filename{};
    std::cout << "Enter the input file: ";
    std::cin >> filename;

    std::ifstream infile { filename };

    if (!infile){
            std::cout << '\n' << filename << " does not exist.\n";
            return 1;
        }

    int num_grades {};
    double final_grade {};
    char letter_grade {};
    int points_earned {};
    int max_points {};
    std::array < int, kMaxSize > grades {};

    max_points = num_grades * 100;
    grades = ProcessFile(infile, num_grades);

    // this is block checking contents to array
    std::cout << '\n';
    for (int i{0}; i < kMaxSize; i++){
            std::cout << grades.at(i) << " ";
        }
    std::cout << '\n';
    // end of block

    final_grade = CalculateFinalGrade(grades, num_grades);
    points_earned = CalculateTotal(grades, num_grades);
    letter_grade = CalculateLetter(final_grade);

    infile.close();

    std::cout << '\n' << "Number of Grades: " << std::setw(11) << std::right << num_grades;
    std::cout << '\n' << "Total Points Earned: " << std::setw(8) << std::right << points_earned;
    std::cout << '\n'  << "Max Possible Points: " << std::setw(8) << std::right << max_points << '\n';
    std::cout << std::fixed << std::setprecision(1);
    std::cout << '\n' << "Final Grade: " << std::setw(7) << std::right << letter_grade << std::setw(8) << std::right << final_grade << "%" << '\n';

    return 0;
}

std::array <int, kMaxSize >  ProcessFile(std::ifstream &infile, int &num_grades){
    int number {};
    std::array < int, kMaxSize > grades {};
    
    infile >> number;
    while (infile){
        for (int i{0}; i < kMaxSize; i++){
            grades.at(i) = number;
            num_grades = num_grades + 1;
            infile >> number;
        }
    }

    return grades;
}

double CalculateFinalGrade(std::array < int, kMaxSize > grades, int &num_grades){
    double final_grade{};
    int max_points {};
    max_points = num_grades * 100;
    double points_earned {};
    for (int i{0}; i < kMaxSize; i++){
            points_earned += grades.at(i);
        }
    if (max_points != 0){
        final_grade = points_earned / max_points * 100;
    } else {
        final_grade = 0;
    }
    return final_grade;
}

int CalculateTotal(std::array < int, kMaxSize > grades, int &num_grades){
    double points_earned {};
    for (int i{0}; i < num_grades; i++){
            points_earned += grades.at(i);
        }
    return points_earned;
}

char CalculateLetter(double final_grade){
    if (final_grade >= 90){
        return 'A';
    } else if (final_grade < 90 && final_grade >= 80){
        return 'B';
    } else if (final_grade < 80 && final_grade >= 70){
        return 'C';
    } else if (final_grade < 70 && final_grade >= 60){
        return 'D';
    } else {
        return 'F';
    }
}

我也尝试过使用for循环,但我遇到了同样的问题。

c++
1个回答
0
投票

查看您的代码(简化)

infile >> number;
while (infile){
    for (int i{0}; i < kMaxSize; i++){
        ...
        infile >> number;
    }
}

由于某种原因,当只需要一个循环时,您使用了两个循环。此代码读取一个数字,检查文件,然后在再次检查文件之前读取

kMaxSize
,如果此时文件正常,它将读取另一个
kMaxSize
数字,依此类推。

您遇到的另一个错误是

while (infile)
。此测试是否已到达文件末尾,但这不是正确的测试,因为可以读取文件中的最后一个数字,而无需到达文件末尾。最好的测试是 while (infile >> number),它测试您是否真的可以读取一个数字,这正是您想要的(大多数时候)。
将其放在一起就是正确的代码

int i = 0; while (i < kMaxSize && infile >> number) { ... ++i; }

	
© www.soinside.com 2019 - 2024. All rights reserved.