New programmer - could use some comments on my code

closed account (zwA4jE8b)
Hi everyone, I am a new c++ programmer and would appreciate if someone had the time to check out some code I wrote and let me know what you think.

The code works, I am just wondering if my algorithms are efficient and if the code is well written and clean.

These are exercises from my book C++ programming and data structures, they are not homework.

This is a text file that accompanies ch9 Problem 6
the first line are the test answers and the subsequent lines are the student ID
followed by the students answers
1
2
3
4
5
TFFTFFTTTTFFTFTFTFTT
STU001 TFFTFFT FTFFFTTFTFFT
STU002 FTTTFFFTFTTFFTFTFTTF
STU003 TFFTFFTTTTFFTFTFTFTT
stu004 TFFTFFTFFFFFTTTFFTFF



This program uses the above text file to calculate a students test score.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
//Michael Ervin - ch9 Problem 6

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

using namespace std;

void getAvgandGrade(int **sArray, double avgArray[], char lArray[], int max);
char letterGrade(double avg);

int main()
{
	//declare all variables
	ifstream infile;
	ofstream outfile;
	string inFileName, outFileName, answer, ID, *answersPerStudent;
	char answers[21], **studentID, *letterGrades;
	int i, j, **studentTest, numStu = 0;
	double *averages;
	char ch;

	//get File Name
	cout << "What is the input filename? ";
	getline (cin, inFileName); cout << endl;
	cout << "What is the output filename? ";
	getline (cin, outFileName); cout << endl;


	infile.open(inFileName.c_str());
	outfile.open(outFileName.c_str());

	if (!infile)
	{
		cout << "Could not open the file." << endl;
		system("PAUSE");
		return 1;
	}

	infile.clear();
	outfile.clear();

	//get the answers
	getline(infile, answer);
	strcpy_s(answers, answer.c_str());

	//count number of lines after (answers) to determine number of students, used to initialize dynamic arrays
	while (getline(infile, answer))
	{
		numStu++;
	}

	studentTest = new int* [numStu];  //create rows
	studentID = new char* [numStu];   //create rows
	averages = new double[20];        //initialize
	letterGrades = new char[21];      //initialize
	letterGrades[20] = '\0';
	answersPerStudent = new string[numStu];
	for (i = 0; i < numStu; i++)      //create columns
		studentTest[i] = new int[20];
	for (i = 0; i < numStu; i++)      //create columns
		studentID[i] = new char[7];

	infile.clear();                   //reset infile
	infile.close();
	infile.open(inFileName.c_str());    //reopen infile

	getline(infile, answer);          //bypass first line

	//fill Student test array with score values, Correct answer = 2 point, Incorrect answer = -1 point, Blank = 0 points
	for (i = 0; i < numStu; i++)
	{
		infile.get(studentID[i], 7, ' ');
		infile.get(ch);
		for (j = 0; j < 20; j++)
		{
			infile.get(ch);
			if (ch == ' ')
				studentTest[i][j] = 0;
			else if (ch == answers[j])
				studentTest[i][j] = 2;
			else if (ch != answers[j])
				studentTest[i][j] = -1;
			answersPerStudent[i] += ch;
		}
		infile.get(ch);
	}

	getAvgandGrade(studentTest, averages, letterGrades, numStu);

	//write grades to file
	for (i = 0; i < numStu; i++)
		outfile << "Student ID: " << studentID[i] << "\n\t" <<
		"Answers: " << answersPerStudent[i] << "\n\t" <<
		"Average: " << averages[i] << "\n\t" <<
		"Grade:   " << letterGrades[i] << "\n\n";

	cout << "The input file has been processed.\n" <<
			"You can view the results in the file \"" << outFileName << "\"" << endl << endl;

	infile.close();
	outfile.close();
	system("PAUSE");
	return 0;
}

//Function to get the average per student
void getAvgandGrade(int **sArray, double avgArray[], char lArray[], int max)
{
	int i, j;
	double avg = 0;
	
	for (i = 0; i < max; i++)
	{
		for (j = 0; j < 20; j++)
			avg += sArray[i][j];
	avg = ((avg / 40) * 100);
	avgArray[i] = avg;
	lArray[i] = letterGrade(avg);
	avg = 0;
	}
}

//function to return the letter grade based on the students average
char letterGrade(double avg)
{
	char letter;
	if (avg >= 90)
		letter = 'A';
	else if (avg >= 80)
		letter = 'B';
	else if (avg >= 70)
		letter = 'C';
	else if (avg >= 60)
		letter = 'D';
	else
		letter = 'F';
	return letter;
}



This program is used to add numbers larger than 2147483647. I am very happy with the algorithm I made for this one.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
//Michael Ervin - ch9 Problem 11
//No validation, so enter only integers.
//delete [] varName will not work for some reason. need to fix

#include <iostream>
#include <iomanip>
#include <string>


using namespace std;

void add(int arr1[], int arr2[], int sum[], int length, bool zerolen);

int main()
{
	//declare all variables
	int i;
	int *num1, *num2, *temp1, *temp2, *sum;
	bool zerolen = false;
	char ch;
	string inputNumber;
	string::size_type len1;
	string::size_type len2;

	cout << "-------------------------------------------\n" <<
			"This program allows you to and and numbers\n" <<
			"larger than 2147483647 with the help of\n" <<
			"*arrays and functions. The dynamic arrays\n" <<
			"allow for you to add numbers with as many\n" <<
			"digits as your computers memory allows\n" <<
			"-------------------------------------------\n" << endl;
	do
	{
		cout << "Enter the first number >> ";
		
		//get user input
		getline(cin, inputNumber);
		len1 = inputNumber.length();
		
		num1 = new int[len1];  //initialize array
		
		//read in user input backwards
		for (i = (len1 - 1); i >= 0; i--)
			num1[i] = (static_cast<int>(inputNumber[(len1 - 1) - i]) - 48);

		cout << "Enter the second number >> ";
		
		//get user input
		getline(cin, inputNumber);
		len2 = inputNumber.length();
		
		num2 = new int[len2];//initialize array

		//read in user input backwards
		for (i = (len2 - 1); i >= 0; i--)
			num2[i] = (static_cast<int>(inputNumber[(len2 - 1) - i]) - 48);

		cout << endl;

		//determine size discrepancies, fill trailing space with 0's
		if (len1 > len2)
		{
			sum = new int[len1];
			temp2 = new int[len1];
			memcpy(temp2, num2, (sizeof(int) * inputNumber.size()));
			for (i = len2; i <= (len1 - 1); i++)
				temp2[i] = 0;
			add(num1, temp2, sum, len1, zerolen);
		}
		else if (len2 > len1)
		{
			sum = new int[len2];
			temp1 = new int[len2];
			memcpy(temp1, num1, (sizeof(int) * inputNumber.size()));
			for (i = len1; i <= (len2 - 1); i++)
				temp1[i] = 0;
			add(temp1, num2, sum, len2, zerolen);
		}
		else if (len1 == len2)
		{
			zerolen = true;
			sum = new int[len1 + 1];
			sum[0] = 0; sum[1] = 0;
			add(num1, num2, sum, len1, zerolen);
		}	
		system("PAUSE");
		cout << "Would you like to add another number(y/n)? ";
		cin >> ch; system("CLS"); cin.clear(); cin.ignore(100, '\n');
	}
	while (ch =='y' || ch == 'Y');

	return 0;
}

//function to add the digits of the two user input numbers and output the sum
void add(int arr1[],int arr2[], int sum[], int length, bool zerolen)
{
	int i, x = 0, carryOver = 0;
	length--;

	if (zerolen == true)
		if (length < 1)
			x = 1;
		else
			x = 0;
		

	for (i = 0; i <= length; i++)
	{
		if (arr1[i] + arr2[i] >= 10)
		{
			sum[length + x - i] = ((arr1[i] + arr2[i]) % 10) + carryOver;
			carryOver = 1;
		}
		else
		{
		sum[length + x - i] = (arr1[i] + arr2[i]) + carryOver;
		carryOver = 0;
		}
		if (zerolen == true)
			sum[0] += carryOver;
	}	
	
	cout << "The sum of the numbers is: ";
	for (i = 0; i <= length + x; i++)
		cout << sum[i];
	cout << endl << endl;
}


Thank you for your time,
-Mike-
closed account (zwA4jE8b)
And I do know of the problem using system("PAUSE"); I changed it to cin.get();
For the sake of learning practices, system("WHATEVER"); is fine, but bad habit for one who wishes to program cross-platform.
If you're going through the trouble of learning something, you might as well learn it right. The portability issue is not really a problem; you can deal with it using macros. The main reason why you shouldn't use system() calls is that they make your code unsafe. A malicious user can take advantage of it. Obligatory link: http://www.cplusplus.com/forum/articles/11153/
Last edited on
closed account (zwA4jE8b)
that is a really good article. nice info.
I'd break up the functions quite a bit more. A 90-line main() is a bit much. I try to keep main() down to 10-15 lines, and other functions below about 25 lines.

You new, but you don't delete. Better would be to use vectors rather than arrays so you don't have to worry about dynamic allocation.

At lines 74, 75, 78 and 87, you read from a stream but you don't check that the stream is still good. If the file is malformed, the code could crash.
closed account (zwA4jE8b)
thanks pan,
every time i used 'delete [] num1;' or 'delete [] num2;' i recieved a compile error. so I just took it out to get the program to work.
besides the container of stl
there are also some smart pointer could be used
like unique_ptr and shared_ptr
they would be included in the C++0x, gcc4.5 support both of them
butunique_ptr is not fully implement by gcc4.5 yet(maybe)
because the unique_ptr can't work well with std::sort
Topic archived. No new replies allowed.