Вы хотите модулировать свой код. Вы хотите разбить свой код на различные функции, где каждая функция выполняет свою задачу или несет свою ответственность.
Вот то, что я смог придумать, используя ваш код. Теперь мой код работает должным образом, однако он отличается от ожидаемых результатов, это может быть связано со значениями, которые вы используете в своих вычислениях. Тем не мение; Вы должны смоделировать свой код в соответствии с тем, что я предлагаю здесь:
main.cpp
#include <string>
#include <vector>
#include <iostream>
#include <ifstream>
#include "Student.h"
char calculateGrade( int score );
void calculateScores( Student& student, const std::string& answers );
int main() {
// Open our file for reading
std::ifstream in;
in.open("Ch8_Ex6Data.txt");
// get the first line to retrieve the test answers
std::string testAnswers;
std::getline(in, testAnswers);
// read the rest of the file and get the students id's and answers
// then populate our vector of students
std::vector<Student> students;
std::string line;
while (std::getline(in, line)) {
// parse each line correctly to populate each student's information
Student s;
s.id_ = line.substr(0, line.find_first_of(' '));
s.testAnswers_ = line.substr(line.find_first_of(' ') + 1);
students.push_back(s);
}
// Now that we have the information we can calculate the test scores
for (auto& s : students)
calculateTestScores(s, testAnswers);
// We can finally print all of the students results
for (auto& s : students)
std::cout << s;
return EXIT_SUCCESS;
}
char calculateGrade(int score) {
float p = score * 2.5f;
if (p >= 89)
return 'A';
if (p >= 79 && p < 89)
return 'B';
if (p >= 69 && p < 79)
return 'C';
if (p >= 59 && p < 69)
return 'D';
if (p < 59 )
return 'F';
return ' ';
}
void calculateTestScores(Student& student, const std::string& answers) {
int score = 0;
int i = 0;
for (auto& c : student.testAnswers_) {
if (c == ' ')
score -= 2;
else if (c == answers[i])
score += 2;
else
score -= 1;
i++;
}
student.score_ = score;
student.grade_ = calculateGrade(student.score_);
}
Student.h
#ifndef STUDENT_H
#define STUDENT_H
// or #pragma once
#include <string>
#include <iostream>
struct Student {
std::string id_;
std::string testAnswers_;
int score_;
char grade_;
};
std::ostream& operator<<( std::ostream& os, const Student& s );
#endif // STUDENT_H
Student.cpp
#include "Student.h"
std::ostream& operator<<(std::ostream& os, const Student& s) {
return os << s.id_ << ' ' << s.testAnswers_
<< ' ' << s.score_ << ' ' << s.grade_
<< '\n';
}
Когда я запускаю этот код в моей среде IDE, я получаю в качестве результата:
ABC54102 T FTFTFTTTFTTFTTF TF 23 F
DEF56278 TTFTFTTTFTFTFFTTFTTF 40 A
ABC42366 TTFTFTTTFTFTFFTTF 34 B
ABC42586 TTTTFTTT TFTFFFTF 22 F
Существует одна возможная проблема, которую я вижу, и она относится к структуре вашего текстового файла. Вышеприведенное может некорректно рассчитать баллы, когда ответы в конце каждой строки в текстовом файле являются пробелами. Таким образом, вам, возможно, придется изменить функцию, которая вычисляет оценку, чтобы включить, сколько ответов было дано для того, сколько должно быть. Я оставлю это как упражнение для вас. Здесь предлагается использовать встроенные функции строки для запроса ее размера или длины.