发布读取文件并使用数组正确存储和检查内容
Issue reading file and using Arrays to store and check content correctly
我正在做一个从文本文件中读取的作业,其中包含对虚构的真假测试的正确答案,然后包含学生 ID、该学生的答案,然后下一行重复另一个学生。我正在尝试遍历文件并将内容存储在数组中,但似乎有问题,因为第三个条目在中途被截断了。
我尝试重写我的循环结构,重命名数组,用单字符版本而不是字符串版本替换新行,甚至给它们自己的 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 FTFTTTTTTTFTTF TF 23 F
DEF56278 TTFTFTTTFTFTFFTTFTTF 40 A
ABC42366 TTFTFTTTTFTFTFFTTF
AB 31 C
C42586 TTTTFTTT TFTFFFTF
21 楼
当我希望它会继续时,因为
ABC54102 T FTFTFTTTFTTTFTTF TF 27 F
DEF56278 TTFTFTTTFTFTFFTTFTTF 40 A
ABC42366 TTTFTTTTTFTFTFFTTF 34 B
ABC42586 TTTTFTTT TFTFFFTF 26 D
我不确定为什么会这样,并且还错误地计算了第一个条目的分数。
这是文本文件。
TTFTFTTTFTFTFFTTFTTF
ABC54102 T FTFTTTTTTTFTTF TF
DEF56278 TTFTFTTTFTFTFFTTFTTF
ABC42366 TTFTFTTTTFTFTFFTTF
ABC42586 TTTTFTTT TFTFFFTF
您在代码中假设学生答案中的字符数始终为 20,但从第三个学生答案开始只有 17 个字符。
您想模块化您的代码。您希望将代码分解为不同的函数,其中每个函数执行自己的任务或有自己的职责。
这是我使用您的代码得出的结果。现在我的代码工作正常,但它与您的预期结果不同,这可能是由于您在计算中使用的值所致。然而;您应该将您的代码建模为我在这里提出的建议:
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
我发现可能存在一个问题,它与您的文本文件的结构有关。当文本文件中每一行末尾的答案都是空格时,上述方法可能无法正确计算分数。因此,您可能必须修改计算分数的函数,以将给出的答案数量与应该有的数量相结合。我会把它留给你作为练习。这里的建议是使用字符串的内置函数来查询它的大小或长度。
我正在做一个从文本文件中读取的作业,其中包含对虚构的真假测试的正确答案,然后包含学生 ID、该学生的答案,然后下一行重复另一个学生。我正在尝试遍历文件并将内容存储在数组中,但似乎有问题,因为第三个条目在中途被截断了。
我尝试重写我的循环结构,重命名数组,用单字符版本而不是字符串版本替换新行,甚至给它们自己的 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 FTFTTTTTTTFTTF TF 23 F
DEF56278 TTFTFTTTFTFTFFTTFTTF 40 A
ABC42366 TTFTFTTTTFTFTFFTTF
AB 31 C
C42586 TTTTFTTT TFTFFFTF
21 楼
当我希望它会继续时,因为
ABC54102 T FTFTFTTTFTTTFTTF TF 27 F
DEF56278 TTFTFTTTFTFTFFTTFTTF 40 A
ABC42366 TTTFTTTTTFTFTFFTTF 34 B
ABC42586 TTTTFTTT TFTFFFTF 26 D
我不确定为什么会这样,并且还错误地计算了第一个条目的分数。
这是文本文件。
TTFTFTTTFTFTFFTTFTTF
ABC54102 T FTFTTTTTTTFTTF TF
DEF56278 TTFTFTTTFTFTFFTTFTTF
ABC42366 TTFTFTTTTFTFTFFTTF
ABC42586 TTTTFTTT TFTFFFTF
您在代码中假设学生答案中的字符数始终为 20,但从第三个学生答案开始只有 17 个字符。
您想模块化您的代码。您希望将代码分解为不同的函数,其中每个函数执行自己的任务或有自己的职责。
这是我使用您的代码得出的结果。现在我的代码工作正常,但它与您的预期结果不同,这可能是由于您在计算中使用的值所致。然而;您应该将您的代码建模为我在这里提出的建议:
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
我发现可能存在一个问题,它与您的文本文件的结构有关。当文本文件中每一行末尾的答案都是空格时,上述方法可能无法正确计算分数。因此,您可能必须修改计算分数的函数,以将给出的答案数量与应该有的数量相结合。我会把它留给你作为练习。这里的建议是使用字符串的内置函数来查询它的大小或长度。