多次读入数组

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 &lt; 20)那样在你的函数中硬编码20。而是传递要处理的行数并执行while (counter &lt; 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 &gt;= 0.70 直接而不是调用 PassFail 并比较一个字符串。

这里还有许多其他问题,您在某一时刻调用 PassFail 但对返回值不执行任何操作。 PassFail 的唯一副作用是cout &lt;&lt; endl,如果这是您的意图,那么在控制台上放置换行符是一个糟糕的决定并且难以阅读。

尝试向您的编译器询问更多警告,这通常有助于发现这些类型的问题。 -Wall -Wextra 为 gcc 工作,您可能需要阅读您的编译器手册...

【讨论】:

以上是关于多次读入数组的主要内容,如果未能解决你的问题,请参考以下文章

如何将 Fortran 输出读入 Python?

替换数组中的多次出现 - Swift 4.1

将多次访问的具有常量值的数组放在哪里?

C#在循环内多次重新初始化数组

根据数组的大小进行多次 api 调用

从数组中多次使用 SKSpriteNode(s)