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:
- Use the Visual Studio IDE to write and test your program.
- Write a complete C++ program from scratch.
- Familiarize yourself with breakpoints, single-step, and memory examination.
- Use command line arguments to select input and output files.
- Use C++ dynamic arrays for run-time data storage.
- Use basic I/O manipulators to format output values.
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++?
- C++ is an object-oriented programming language that associate classes and objects with attributes and methods. For example: in real life, a car is an object. The car has attributes, such as weight and color, and methods, such as drive and brake.
- Statements are the smallest independent unit of computation and most (but not all) statements end in a semicolon.
- Variables are symbolic names (labels) for memory locations that are defined either as local (automatic) – declared within a function and allocated on stack at run-time or global (static) – declared outside a function and allocated at compile time.
- Operators are symbols that perform operations on values and variables and have precedence and associativity and can be overridden.
- Expressions are formed by combining variables with operators that evaluate to a single value.
- Functions are expressions consisting of a group of statements.
Python vs C++
Main Differences:- C++ is a static (strongly) typed language that is closer to C or Java,
while Python is a flexible or dynamic (weakly) type language.
- Unlike Python you will be forced to declare Variables, Arrays, and other Data Structures with a type.
- C++ will have you dealing with memory allocation whereas Python takes care of this for you, which means you will need to learn more about memory and pointers and a bunch of stuff that stems from lower level programming languages.
- The sum of the first two differences are the main reason C++ is so fast!
- C++ also focuses on OOP (object oriented programming) more than Python.
- Both C++ and Python are C family languages (C++ is specifically an extension of the C language), which means they share the same general syntax.
- Finally, you're not "switching" from Python to C++ as a great many C++ programmers also use scripting languages, and Python is one of the very best companions because of its easy and simple object orientation.
On-line references for learning C++
The following on-line references are just a few of the gazillion websites available for learning C++:
- Youtube (with advertizing, clion, 1 hour): C++ Tutorial for Beginners - Learn C++ in 1 Hour.
- Youtube (gcc, 4 hours): C++ Tutorial for Beginners - Full Course.
- Learn C++: Learn C++.
- W3 Schools: C++ Tutorial.
- tutorialspoint: C++ Tutorial.
- Denison University (long read but thorough): A Transition Guide: Python to 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.
- 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!
- Output the average score for each exam (rounded to one decimal place.)
- 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).
- 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.)
- 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.)
- Test for and eliminate all memory leaks.
Helps and Hints
Parsing an Input Text File.(collapse)
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:
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.
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.
To set command line arguments in XCode 12.3, select Menu Item Product -> Scheme -> Edit Scheme -> Arguments Tab -> Arguments Passed on Launch.
Watch " How to set up input and output files for Visual Studio, CLion, and Xcode" to learn more of command line arguments.
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; }
Reading from a file.(collapse)
- 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');
- 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
- 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;
- 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)
Since new is used in creating the dynamic array, the array must be deleted to prevent memory leaks:int size = 100; int *myStringArray = new string[size]; for(int i = 0; i < size; ++i) { myStringArray[i] = string("name"); // repeat for size strings }
delete [] myStringArray;
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:int rows = 100; int cols = 200; int **myArray = new int*[rows]; for(int i = 0; i < rows; ++i) { myArray[i] = new int[cols]; }
for(int i = 0; i < rows; ++i) { delete [] myArray[i]; } delete [] myArray;
Detecting Memory Leaks.(collapse)
- 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
- 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; }
- 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:
- Zip all your lab source files (.cpp, .hpp, .h) into one folder. DO NOT INCLUDE YOUR WHOLE PROJECT!
- Submit your zipped lab source using the "Labs" tab on the class website.
- Your submitted lab source will be compiled and executed using a lab g++ compiler.
- Both input and output files will be specified by command line arguments.
- An auto-grader will compare your output files with expected results and you will shortly receive an accumulative score.
- The auto-grade process may abort on the first error. For instance, your submission will be immediately rejected if you use STL vectors. If so, correct the error and try again.
- Please, do not use system("pause"); in your submitted source files!
- You may re-submit your zipped source as many times as you like.
Use the following test input and resulting output files in testing your Grades lab.
Input File | Output 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 |
||
---|---|---|---|
The lab source will be peer reviewed using the following rubric:
No |
Partial |
Yes
|
||
---|---|---|---|---|
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. |