Lab 01 - Grades (05/05/2023)


Description

"Write a program that reads from an input file a person's name followed by all their exam scores. Calculate and write the average score for all students on each exam to an output file. Then, write each student's name to the output file followed by the student's score and grade on each exam."

Learning Outcomes

By completing the Grades Lab, you will be able to:


Preparation

Install Visual Studio Community 20xx on your computer.

Documentation and installation steps for Windows Visual Studio 20xx can be found here.


Moving from Python to C++

What is C++?

Python vs C++

Main Differences:

On-line references for learning C++

The following on-line references are just a few of the gazillion websites available for learning C++:


The Lab

Lab requirements:

Use command line argument #1 (argv[1]) to open the input file and command line argument #2 (argv[2]} to open the output file.

  1. Read and output student scores from the input file.
    • The first line of the input file has the number of students and exams.
    • Subsequent lines contain the student name (one or more words delimited by spaces, no digits) followed by integer scores for each exam (also delimited by spaces).
    • All students have the same number of exam scores.
    • Store the student names in a dynamic string array (no vectors).
    • Store the exam scores in a two-dimensional dynamic integer array (one row for each student, one column for each exam score, ie. # students x # of exams.)
    • Again, use dynamic arrays and not a vectors or Variable Length Arrags (VLA's) to store student names, exam scores, and averages!
  2. Output the average score for each exam (rounded to one decimal place.)
  3. Output each student's exam grade in evenly spaced columns - the student score followed by their grade in parentheses.
    • If the student's score is within + or - 5 points of the average, give a grade of C.
    • If the grade is more than 5 points but less than 15 points above (or below) the average, give a grade of B (D).
    • If the grade is 15 points or more above (or below) the average, give a grade of A (E).
  4. Output for each exam the number of student grades for A's, B's, C's, D's, and E's. (List the letter grade in parentheses after the number of grades.)
  5. Extra Credit: Calculate average score of all exams and output each students final score followed by letter grade in parentheses (average student exam scores and grade according to class final average score.)
  6. Test for and eliminate all memory leaks.

Helps and Hints

Parsing an Input Text File.(collapse)

  1. The function main() has two arguments, traditionally called argc and argv. Argc is of type int and is the number of parameters from a command line used in calling the function main. Argv is of type char** and is an array of C string pointers. Argv[0] points to the first parameter on a command line (which is the command), argv[1] points to the second, and so forth. (The size of argv is argc.)

    Use argv[1] for the name of the input file and argv[2] for the name of the output file. The following is an example of how to open files for reading and writing:

  2. if (argc < 3)
    {
       cerr << "Please provide name of input and output files";
       return 1;
    }
    cout << "Input file: " << argv[1] << endl;
    ifstream in(argv[1]);
    if (!in)
    {
       cerr << "Unable to open " << argv[1] << " for input";
       return 2;
    }
    cout << "Output file: " << argv[2] << endl;
    ofstream out(argv[2]);
    if (!out)
    {
       in.close();
       cerr << "Unable to open " << argv[2] << " for output";
       return 3;
    }
  3. To set command line arguments in Visual Studio, right click on project name and select Properties. Under the Configuration Properties, select Debugging and enter Command Arguments.

  4.  

  5. To set command line arguments in CLion:

    • From the main menu, select Run | Edit Configurations or choose Edit Configurations from the run/debug configurations selector on the toolbar.
    • In the Run/Debug Configurations dialog that opens, select a configuration where you want to pass the arguments.
    • Enter the arguments in the Program arguments field. (The arguments should be separated with spaces.)
    • Put your input files in the cmake/build/debug folder.
  6.  

  7. To set command line arguments in XCode 12.3, select Menu Item Product -> Scheme -> Edit Scheme -> Arguments Tab -> Arguments Passed on Launch.

  8.  

  9. Watch " How to set up input and output files for Visual Studio, CLion, and Xcode" to learn more of command line arguments.

Reading from a file.(collapse)

  1. Use extraction operator (">>") to read directly from the input stream:
    int num_students;
    int num_exams;
    in >> num_students >> num_exams;
    // Skip the rest of the line
    in.ignore(std::numeric_limits<int>::max(), '\n');
  2. Use getline to read a line from the input stream - process the string as needed:
    string line;
    getline(in, line);
    size_t p = 0;
    while (!isdigit(line[p])) ++p;	// line[p] is the first digit
  3. Instantiate an istringstream object with an input line and use the extraction operator (">>") to read data from the stream:
    string line = line.substr(p);
    // Put line into an istringstream
    istringstream iss(line);
    iss >> scores;
  4. You should use IO manipulators fixed, setw, and setprecision (found in header <iomanip>) to format output:
    out << std::setw(20) << name << " ";
    out << std::fixed << std::setprecision(0) << std::setw(6) << scores;

C++ two-dimensional dynamic arrays.(collapse)

A dynamic 1D string array is basically an array of C++ string objects. You should initialize it using a loop, like this:
int size = 100;
int *myStringArray = new string[size];
for(int i = 0; i < size; ++i)
{
    myStringArray[i] = string("name");   // repeat for size strings
}
Since new is used in creating the dynamic array, the array must be deleted to prevent memory leaks:
delete [] myStringArray;
A dynamic 2D array is an array of pointers to arrays. You should initialize it using a loop, like this:
int rows = 100;
int cols = 200;
int **myArray = new int*[rows];
for(int i = 0; i < rows; ++i)
{
    myArray[i] = new int[cols];
}
Again, since new is used in creating the dynamic arrays, all column arrays must be deleted followed by deleting the row array to prevent memory leaks:
for(int i = 0; i < rows; ++i)
{
    delete [] myArray[i];
}
delete [] myArray;

Detecting Memory Leaks.(collapse)

To detect memory leaks in Visual Studio:

  1. Place the following code near the beginning of the file containing your main function:

    #ifdef _MSC_VER
    #define _CRTDBG_MAP_ALLOC  
    #include <crtdbg.h>
    #define VS_MEM_CHECK _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
    #else
    #define VS_MEM_CHECK
    #endif

  2. Put the following C pre-processor macro at the beginning of your main code:

    int main(int argc, char * argv[])
    {
       VS_MEM_CHECK               // enable memory leak check
       // Your program...
       return 0;
    }

  3. If you get something like the following when your program exits, YOU HAVE A MEMORY LEAK! You are required to remove all memory leaks.

    The thread 0x34bc has exited with code 0 (0x0).
    Detected memory leaks!
    Dumping objects ->
    {149} normal block at 0x00365008, 4000 bytes long.
     Data: <                > 01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 
    Object dump complete.
    The program '[4984] Lab 01 - grades.exe' has exited with code 0 (0x0).
    

Understanding Valgrind Output.(collapse)

  • You can find helpful hints and explanations of Valgrind output here.

Grades Grading Criteria

Instructions for submitting your lab:

Use the following test input and resulting output files in testing your Grades lab.

Input FileOutput File
Test #1 lab01_in_01.txt lab01_out_01.txt
Test #2 lab01_in_02.txt lab01_out_02.txt
Test #3 lab01_in_03.txt lab01_out_03.txt

 

Given the following input file:

2 3
Cody Coder 100 90 96
Harry Houdini 60 80 72

the auto-grader will be expecting to find in your output files the following:

Fail
Pass
Score = 0

 

The lab source will be peer reviewed using the following rubric:

No
Partial
Yes
Score = 0
Overall
Rating
Easy to follow, readable, organized, and well commented.
                      
***NOTE: Any attempt to circumvent any lab requirement (ie, hard coding
output, using loops instead of iterators where required, modifying a class interface, etc.) will be reported by peer reviewers and result in a zero score for the lab.
Total Score = 0