多次读入数组
Posted
技术标签:
【中文标题】多次读入数组【英文标题】:Reading into an Array Multiple Times 【发布时间】:2016-08-25 08:33:28 【问题描述】:我的代码有点问题。它几乎应该打开两个文件,并将文件“StudentAnswers.txt”的前二十行[作为字符输入到字符数组中]与(另一个文件的每一行)“CorrectAnswers.txt”中的字符值进行比较在同一位置(索引)的另一个数组中。这就像线性搜索,但在数组中的位置相同。然后应该显示一份报告,详细说明学生错过了哪个问题、给出的答案、正确答案,以及学生是否通过(获得 >= 70%),如下所示:
学生 X 的报告: 2 (A/D), 3 (C/D), 5(D/A) 这位学生通过了考试!
然后它应该清除 SAArray,并从 StudentAnswers.txt 提供接下来的 20 行,然后重新开始该过程。我猜程序必须从('StudentAnswers.txt'文件的行/20行)确定学生人数。
我在显示报告时遇到问题,并且在程序结束后让数组自行清除。我猜这可以通过一个while循环和一个学生数量的累加器来完成(由上面的等式确定)。 此外,Visual Studio 似乎转到“错过了 __ 个问题,共 ___ %”,然后继续循环 -858993460。
任何帮助将不胜感激。
#include <iostream>
#include <fstream>
#include <string>
#include <array>
#include <algorithm>
using namespace std;
void GradeReturn(char[], char[], int, int, int);
string PassFail(float);
int main()
ifstream SA("StudentAnswers.txt");
ifstream CA("CorrectAnswers.txt");char CAArray[20];
char SAArray[20];
// char SA2Array[20];
bool isCorrect;
int correct;
int incorrect;
int counter;
correct = 0;incorrect = 0;
counter = 0;
cout << endl;
if (!SA.fail())
cout << "'StudentAnswers.txt' file opened successfully." << endl;
cout << "'CorrectAnswers.txt' file opened successfully." << endl << endl;
int a = 0;
int b = 0;
while (a < 20)
CA >> CAArray[a];
a++;
// while loop to feed char into the array
while (b < 20)
SA >> SAArray[b];
b++;
// while loop to feed char into array
CA.close(); // closing "CorrectAnswers.txt"
SA.close(); // closing "StudentAnswers.txt"
GradeReturn(&CAArray[counter], &SAArray[counter], correct, incorrect, counter);
return 0;
void GradeReturn(char CAArray[], char SAArray[], int correct, int incorrect, int counter)
float percent;
float hundred;
int student;
int catcher[20];
int writeCatcher; int starter;
int catcher_size;
student = 0;
writeCatcher = 0;
catcher_size = ((sizeof catcher) / 4);
while (counter < 20)
if ((CAArray[counter]) == (SAArray[counter]))
correct++;
cout << "Good job!" << endl;
// correct handling
else
incorrect++;
cout << "You got question " << counter << " wrong." << endl;
counter >> catcher[writeCatcher];
writeCatcher++;
// incorrect handling
counter++;
// while loop to determine if a student got a question right or wrong
static_cast <float> (incorrect); // float conversion
cout << endl; // for cleanliness
percent = ((static_cast <float> (correct)) / 20); // percentage
hundred = percent * 100;
PassFail(percent);
if (PassFail(percent) == "pass")
student++;
cout << "Report for Student " << student << ":" << endl;
cout << "-----------------------------" << endl;
cout << "Missed " << incorrect << " questions out of 20 for ";
cout << hundred << " % correct." << endl << endl;
starter = 0;
while (starter < (sizeof catcher)
if(1=1)
catcher_size
else
cout << "";
starter++;
else if (PassFail(percent) == "fail")
student++;
cout << "Missed " << incorrect << " questions out of 20 for ";
cout << hundred << " % correct." << endl << endl;
while (starter < catcher_size)
if ((catcher[starter]) == -858993460)
starter++;
else
cout << "";
starter++;
return;
string PassFail(float percent)
if (percent >= 0.70) // if <pass>
return "pass";
else // if <fail>
return "fail";
cout << endl;
【问题讨论】:
您可以考虑直接返回 True 或 False 表示通过或失败并跳过字符串比较。如果您想“让它看起来更好”,请考虑使用枚举映射返回通过和失败。 【参考方案1】:要获得循环,您应该保持流打开而不是在阅读 20 行后关闭它们。
作为伪代码:
a = 0;
while(streams_not_empty)
CA >> CAArray[a];
SA >> SAArray[a];
++a;
if (a == 20)
GradeReturn(&CAArray[counter], &SAArray[counter], correct, incorrect, counter);
a = 0; // Reset a
CA.close(); // closing "CorrectAnswers.txt"
SA.close(); // closing "StudentAnswers.txt"
您还需要通过引用传递correct, incorrect, counter
,以便GradeReturn
可以更改它们的值并通过累积。
喜欢:
void GradeReturn(char CAArray[], char SAArray[], int& correct, int& incorrect, int& counter)
此外,您不应该依赖每次都能从文件中准确读取 Nx20 行。一个文件可能有,例如108 (5x20 + 8) 行,所以你的代码应该能够处理只有 8 行。换句话说,不要像while (counter < 20)
那样在你的函数中硬编码20。而是传递要处理的行数并执行while (counter < number_to_handle)
。
类似这样的伪代码:
a = 0;
while(streams_not_empty)
CA >> CAArray[a];
SA >> SAArray[a];
++a;
if (a == 20)
GradeReturn(&CAArray[counter], &SAArray[counter], correct, incorrect, counter, a);
// ^
a = 0; // Reset a
if (a != 0)
// Process the rest
GradeReturn(&CAArray[counter], &SAArray[counter], correct, incorrect, counter, a);
CA.close(); // closing "CorrectAnswers.txt"
SA.close(); // closing "StudentAnswers.txt"
【讨论】:
【参考方案2】:您遇到的一个问题是您试图将 C 风格的字符串与 ==
运算符进行比较。这会将它们本质上进行比较,就好像它们是指向 char
的指针一样,即比较它们是否指向内存中的同一位置,而不是比较字符串的内容。我敦促您查看数组衰减和 c-string 变量以了解更多信息。
具体来说,if (PassFail(percent) == "pass")
不会做你想做的事。 strcomp
doc, strncmp
doc 使用std::string
变量而不是c 风格的字符串都可以,但最好将percent
与一个值进行比较,即if(percent >= 0.70
直接而不是调用 PassFail 并比较一个字符串。
这里还有许多其他问题,您在某一时刻调用 PassFail 但对返回值不执行任何操作。 PassFail 的唯一副作用是cout << endl
,如果这是您的意图,那么在控制台上放置换行符是一个糟糕的决定并且难以阅读。
尝试向您的编译器询问更多警告,这通常有助于发现这些类型的问题。 -Wall -Wextra 为 gcc 工作,您可能需要阅读您的编译器手册...
【讨论】:
以上是关于多次读入数组的主要内容,如果未能解决你的问题,请参考以下文章