hello

we have to make a program that grades multiple choice exams from input files by the user and outputs the id of each student followed by their appropriate score.

here are the input files:

exam file

abcdefabcdefabcdefab
1234567 abcdefabcdefabcdefab
9876543 abddefbbbdefcbcdefac
5554446 abcdefabcdefabcdef
4445556 abcdefabcdefabcdefabcd

where the first line is the answer key, and the first column of numbers is 4 student ids, followed by the second column of their answers. in this case, the program compares the answers with the answer key and outputs the scores to each of the ids on the output file.

curve file

A     90
B     80
C     70
D     60
E     50

i didnt know how to implement this exactly. the professor showed us to make the if statements as seen in my code about if <=90 for say, "A". and so on. this is what the rubric says : "This second file contains the information to convert a percentile score to a curved grade in levels of ‘A’ through ‘E’. For instance, a grade-curving file takes the following format: a curved alphabetic grade, a space, a percentile grade served as marker."

output file example

1234567 90%  A
9876543 85%  B
5554446 95%  A
4445556 75%  C
5551112 80%  B
Statistics:
    Average Score: 85%
    Minimum Score: 95%
    Maximum Score: 75%

and here is my code:

#include <iostream>
#include <string>
#include <fstream>

using namespace std;

int openFiles(ifstream& inFile, ifstream& curvingFile, ofstream& outFile);

void size(ofstream& outFile, int keylength, string answers, string key, string id);

int main()
{

    ifstream inFile, curvingFile;
    ofstream outFile;

    int num_student = 4;
    string key, id, answers, w[6];
    int keylength;
    char x;

    int open = openFiles(inFile, curvingFile, outFile);
    if (open != 3)
    {
        cout << "There was an error opening the corresponding files. Check input name perhaps?" << endl;
        return 0;
    }

    //program initiates here...



    /*while (inFile >> id[0] >> answers)
    {
        outFile << id << " ";
        size(outFile, keylength, answers, key);
    }*/// this is a temporary old code. keeping it in case....

    do {
        openFiles(inFile, curvingFile, outFile);  // function calling

        inFile >> key; // answer key
        keylength = key.length();// length represents number of questions in exam from exam1.dat

        inFile >> id[0];

        inFile >> answers;

        for (int i = 0; i < num_student; i++) // loop over each student

        {
            size(outFile, keylength, answers, key, id);

        }
        cout << "Would you like to attempt a new trial? (y/n): ";

        cin >> x;

        } while (x == 'y' || x == 'Y');

    system("pause");
    return 0;
}

int openFiles(ifstream& inFile, ifstream& curvingFile, ofstream& outFile)
{
    string inFileName, curvingFileName, outFileName;

    cout << "Input the name of the input file: " << endl;
    cin >> inFileName;
    inFile.open(inFileName.c_str());

    cout << "Input the name of the curving file: " << endl;
    cin >> curvingFileName;
    curvingFile.open(curvingFileName.c_str());

    cout << "Input the name of the output file: " << endl;
    cin >> outFileName;
    outFile.open(outFileName.c_str());
    //outFile << "These are the student scores for " << inFileName << endl; // this is a general statement that identifies what the scores are for...the name if inFile name that is
    //outFile << fixed;

    return true;
}

void size(ofstream& outFile, int keylength, string answers, string key, string id)
{
    int length, grade = 0, score2;
    float score;
    bool check;

    if (answers.length() < keylength)
    {
        outFile << "the unanswered questions were counted as incorrect answers";
    }
    /*else if (answers.length() > keylength)
    {
        outFile << "Unnecessary extra answers"; // how do i automatically make it truncate?
    }*/
    else
    {
        check = false;
    }

    for (int count = 0; count < key.length(); count++)
    {
        if (answers[count] == key[count])
        {
            grade++;
        }

        score = (float)grade / keylength;
        score2 = (int)(score * 100);

        /*else if (answers[count] != 'a' && answers[count] != 'b' && answers[count] != 'c' && answers[count] != 'd' && answers[count] != 'e' && answers[count] != 'f')
        {
        check = true;
        }

        if (check == true)
        {
        outFile << "Invalid Answer";
        }*/ // this long comment states that if the student has some different answer like g or h that is not even something in the answer key, check = true.

        outFile << id << "     " << score2 << "%"; // else needed here with brackets that include the outfile << grade; (original one instead of outFile << id <<....) if activate above comments 

        if (score2 >= 90)//<-----w[0]

            outFile << "A" << endl;

        else if (score2 >= 80)//<-----w[1]

            outFile << "B" << endl;

        else if (score2 >= 70)//<-----w[2]

            outFile << "C" << endl;

        else if (score2 >= 60)//<-----w[3]

            outFile << "D" << endl;

        else if (score2 >= 50)//<-----w[4]

            outFile << "E" << endl;

        else if (score2 < 50)//<-----w[5]

        outFile << "F" << endl;
    }
        outFile << endl;
    }

i worked really hard on this, spending about 30 hours over the last days and week. as a beginner, i managed to do this much (85%) and i am facing the problems of "Cannot find or open the PDB file."

am i supposed to place the files in a special place for the program to read it? i dont know what is going on, cause its not identifying the files even though i tried many ways of renaming back in the project directory the input files and inputting that name into the console questions, yet it terminates with that statement.

also, how do i make a statistics category to output to the outfile? i dont know how to make maximum score, minimum score, and average score. i have the idea of

int max = score2
int min = score2
float average

if (score2> "i wanna say here than all other scores, but dont know how")

outFile << "maximum score is " << max <<endl;

if (score2< all other scores)

outFile << "minimum score is " << min << endl;

average=(score2+score2+score2+score2)/4

outFile << "the average score is" << average << endl;

//i am sure this is incorrect and missing, but thats what i had in mind

thnx anyone in advance!

Recommended Answers

All 4 Replies

Maybe it is a matter of the exact pathname?
I suggest to leave this program for a day or two.
Google for a simple example of file IO. Once you practice your reading and writing ability of a simple textfile and it works, then return to your project.

Ok, here is what I see. I see that you have worked hard on developing this program,but there is something I don't understand. In your function--> int openFile(File1, File2, File3) I see that you test if 3 files were open after the function returns to main, but what I see in the function is you returning a BOOL (true) when the function is supposed to return an integer (isn't it?). Try this: each time you successfully open a file in the openFiles() you could add one to an accumulator if(success) or keep the accumulator at whatever it was at(declare it as 0 at the top somewhere) and then return that accumulator at the end of the function. To be direct about it, the variable open will never, ever be == 3 if the function returning value to that variable doesn't accumulate anything and just returns true. Maybe I'm missing something, but I think that might be a problem.

as a beginner, i managed to do this much (85%) and i am facing the problems of "Cannot find or open the PDB file."

PDB files are files that are specific to Visual Studio projects. This is a problem with setting up your C++ project. Are you able to run a simple "Hello World" program? Did you make sure the follow all the steps to create a win32 console application in Visual Studio?

You might want to consider using a simpler (lighter-weight) IDE like CodeBlocks instead (make sure the download / install the version with MinGW). It uses a simpler (and less troublesome) project configuration system than Visual Studio.

am i supposed to place the files in a special place for the program to read it?

If you provide absolute paths, then it does not matter. If you provide relative paths, then they will be relative to the place where the executable runs from (which is kind of unclear in Visual Studio). Just locate the folder in which the "*.exe" file for you project was generated (it is usually in the "debug" or "release" directories of your project folder). I'm sorry, it's been a long time since I've used Visual Studio with default build configurations (I, like most experts, use other external build configuration-script systems).

Also, your input method:

cout << "Input the name of the input file: " << endl;
cin >> inFileName;
inFile.open(inFileName.c_str());

will only capture the first word in the file path. So, if you have a file path like C:\\My Documents\\something.txt, then the file path that will be read into the string inFileName will be C:\\My only. If you want to read the entire line, you need to read the entire line, with the getline function:

cout << "Input the name of the input file: " << endl;
getline(cin, inFileName);
inFile.open(inFileName.c_str());

That might be the source of the problem. A good way to debug this kind of error is to just print out the value:

cout << "Input the name of the input file: " << endl;
cin >> inFileName;
cout << "Input file name = " << inFileName << endl;
inFile.open(inFileName.c_str());

There are a number of other problems in your code, but I can't just go through each of them. You have to learn to do things one step at a time. You should never write an entire program like that, just to find that you have trouble with the very first step (opening the files). You should first write the bit of code that opens the files, then compile, run, and verify that it works up to that point. Then, you do the next thing (e.g., read the student IDs and answers), and then print out the immediate results of that, compile, run, and verify that it works up to that point. And so on, so forth.

commented: No one can beat the deepness of your explanations. +15

thnx everyone; since the project was due today i was persistent to finish it and with some more help, like it turned out i didnt #include cstring, and i was supposed to put them as .txt in the console the names of files. there was a major change too, but ya. i got it. thnx everyone though!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.