Проблема чтения файла и использование массивов для правильного хранения и проверки содержимого - PullRequest
0 голосов
/ 08 июля 2019

Я работаю над заданием, которое читает из текстового файла, который содержит правильные ответы на вымышленный тест на истину или ложь, а затем содержит идентификатор ученика, ответы этого ученика, а затем повторяется следующая строка с другим учеником , Я пытаюсь просмотреть файл и сохранить содержимое в массивах, но, похоже, что-то не так, поскольку третья запись обрезается на полпути.

Я попытался переписать структуру моего цикла, переименовать массивы и заменить новые строки односимвольными версиями вместо строковых версий и даже дать им собственный оператор cout.

string studentId;
char answers [20];
char response;
int testScore = 0;

ifstream inFile;
inFile.open ("Ch8_Ex6Data.txt");

for (int i=0; i<20; i++)
    {
    inFile >> answers [i];
    }

    while ( ( inFile >> studentId))
        {
        cout << '\n' << studentId << ' ';
        inFile.get(response);
        testScore = 0;
        for (int i = 0; i < 20; i++)
            {
            inFile.get (response);
            cout << response;
            if (response == ' ')
                {
                testScore = testScore - 2;
                }
                else if (response == answers [i])
                {
                testScore = testScore + 2;
                }
                else
                {
                testScore = testScore -1;
                }
            }
            cout << ' ' << testScore << ' ';
            double p = testScore * 2.5;
            if (p >= 89)
                {
                cout << 'A';
                }
            else if (p >=79)
                {
                cout << 'B';
                }
            else if (p >=69)
                {
                cout << 'C';
                }
            else if (p >=59)
                {
                cout << 'D';
                }
            else if (p <= 59)
                {
                cout << 'F';
                }
        }
    inFile.close();
    return 0;
    }

Я получаю вывод
ABC54102 T FTFTFTTTFTTFTTF TF 23 F
DEF56278 TTFTFTTTFTFTFFTTFTTF 40 A
ABC42366 TTFTFTTTFTFTFFTTF
AB 31 C
C42586 TTTTFTTT TFTFFFTF

21 F

Когда я надеялся, что это продолжится, как

ABC54102 T FTFTFTTTFTTFTTF TF 27 F
DEF56278 TTFTFTTTFTFTFFTTFTTF 40 A
ABC42366 TTFTFTTTFTFTFFTTF 34 B
ABC42586 TTTTFTTT TFTFFFTF 26 D

Я не уверен, почему он это делает, а также неправильно рассчитывает балл за первые записи.

Это текстовый файл.
TTFTFTTTFTFTFFTTFTTF
ABC54102 T FTFTFTTTFTTFTTF TF
DEF56278 TTFTFTTTFTFTFFTTFTTF
ABC42366 TTFTFTTTFTFTFFTTF
ABC42586 TTTTFTTT TFTFFFTF

Ответы [ 2 ]

1 голос
/ 09 июля 2019

Вы хотите модулировать свой код. Вы хотите разбить свой код на различные функции, где каждая функция выполняет свою задачу или несет свою ответственность.

Вот то, что я смог придумать, используя ваш код. Теперь мой код работает должным образом, однако он отличается от ожидаемых результатов, это может быть связано со значениями, которые вы используете в своих вычислениях. Тем не мение; Вы должны смоделировать свой код в соответствии с тем, что я предлагаю здесь:

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

Существует одна возможная проблема, которую я вижу, и она относится к структуре вашего текстового файла. Вышеприведенное может некорректно рассчитать баллы, когда ответы в конце каждой строки в текстовом файле являются пробелами. Таким образом, вам, возможно, придется изменить функцию, которая вычисляет оценку, чтобы включить, сколько ответов было дано для того, сколько должно быть. Я оставлю это как упражнение для вас. Здесь предлагается использовать встроенные функции строки для запроса ее размера или длины.

0 голосов
/ 08 июля 2019

Вы предполагали в своем коде, что количество символов в ответах ученика всегда равно 20, но, начиная с ответов третьего ученика, есть только 17 знаков.

...