我必须使用包含不同数量数字的各种文件并计算某些总数。我的代码遇到的唯一问题是,当我从文件中读取并将数字传递到数组中时,文件中的最后一个数字在它应该结束时被重复接受到数组中。请帮助解决这个问题,我不明白为什么它到达文件末尾后就不会停止。
我的代码如下:
#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循环,但我遇到了同样的问题。
查看您的代码(简化)
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;
}