Working with arrays on the heap

Pages: 12
scores is a 2D array, yet you call it as if it's a 1D array at line 94. That seems to be your main error. I'm surprised your code even compiles, I would make your compiler have stricter flags if possible. I think some other parts of your logic are wrong, though.

You also most likely want to divide after the loop
1
2
3
4
5
6
        for (int i(0); i != 5; i++)
        {
            sum_of_test_scores += scores[i];
        }
        average = sum_of_test_scores / 5.0;
        cout << "The average is: " << average << endl;

Also notice the 5.0, it's needed because sum_of_test_scores is an int, so it would truncate your value otherwise.
Last edited on
It is a thing when you use a mac you can't use inputFile.ignore(); (or at least when you use Xcode.... so yea this is good to know)

That sounds like a misunderstanding.

Yes you should be happy that you have moved past an obstacle. However, I'm not convinced that you actually understand what the obstacle was, and have merely found some work-around which happens to be satisfactory.

You could probably have used cin.ignore(100, '\n'); in this case. That would have been a reasonable suggestion regardless of compiler or OS.

However, the key step would be to examine the file contents with a suitable tool such as a hex editor in order to diagnose the actual problem.

Simple program to display actual line-ending characters:
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
#include <iostream>
#include <fstream>
#include <cctype>

using namespace std;

int main()
{ 
    ifstream inputFile("Student Data.txt", ios::binary);
    
    char ch;
    
    while (inputFile.get(ch))
    {
        if (!iscntrl(ch))    
        {
            cout << ch;
        }
        else if (ch == '\n')
        {
            cout << "[\\n]" << endl;
        }
        else if (ch == '\r')
        {
            cout << "[\\r]" << endl;
        }
        else
        {
            cout << '[' << int(ch) << ']';
        }
    }
    
    return 0;
}

Last edited on
@ Chervil

I tried the cin.ignore(100, '\n'); and it did not work. I guess I am going to have to stick with what I have but thanks any why! But I am going to try that program you showed me and see if any of them work :)
-------------------------------------------------------------------------------------------

So I have fixed the 2D array (and it was giving me a flag just I could still run it) that was a noob move on my part :). However my average is still not right. Its loser but not right. As well at my if/else to get the letter grade is better but not right. code and output listed bellow:

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
141
142
143
144
145
146
147
148
149
150
151
152
//  main.cpp
//  Program 8
//  Created by William Blake Harp on 7/16/14.

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

using namespace std;

int main()
{
    double average = 0;
    double class_average = 0;
    int sum_of_test_scores = 0;
    
    //2D Array.
    const int students = 5;
    const int test_scores = 4;
    int scores[students][test_scores];
    
    //Arrays on the heap.
    string* arrayNames = nullptr;
    arrayNames = new string[students];
    
    int* arrayID = nullptr;
    arrayID = new int[students];
    
    int* arrayAverage = nullptr;
    arrayAverage = new int[students];
    
    int* arrayLetterGrade = nullptr;
    arrayLetterGrade = new int[students];
    
    ifstream inputFile;

    // Open the file.
    inputFile.open("Student Data.txt");
    
    // do an initial test.
    cout<<boolalpha;
    cout<< "Is the file good? --> "<<inputFile.good()<<endl<<endl;
    
    if (inputFile.fail())
        cout << "Can't open the file!" << endl;
    
    else
    {
        for( int i(0); i != 5; i++ )
        {
            // read name.
            getline(inputFile, arrayNames[i]);
            cout<<arrayNames[i]<<endl;
            
            // read student id.
            inputFile >> arrayID[i];
            cout<< arrayID[i] <<endl;
            
            // read four(4) scores.
            for( int j(0); j != 4; j++ )
            {
                inputFile >> scores[i][j];
                cout << scores[i][j] << endl;
            }
            
            string str;
            
            // consume '\n' char (Use getline for mac/Xcode!!!).
            getline (inputFile, str);
            
        
            cout << "I have read "<<i+1 <<" record/s\n\n";
        }// end read loop.
    
        // display student name and scores.
        for( int i(0); i != 5; i++ )
        {
            cout << arrayNames[i] << "  ";
            
            for( int j(0); j != 4; j++ )
            {
                cout << scores[i][j] << " ";
            }
            
            cout << endl << endl;
        }// End display name & scores.
        
        // Loop for average.
        for (int i(0); i != 5; i++)
        {
            for (int j = 0; j != 4; j++)
            {
                sum_of_test_scores += scores[i][j];
            }
        }
        average = sum_of_test_scores / 5.0;
        cout << "The average is: " << average << endl;
        
        // Loop for grade.
        for (int i = 0; i != 5; i++)
        {
            // Geting a letter grade.
            if (average > 100)
            {
                cout << "invalid average for grade please try again." << endl;
            }
            else if(average >= 90 && average <= 100)
            {
                cout << "Letter grade is A!" << endl;
            }
            else if (average >= 89 && average <= 80)
            {
                cout << "Letter grade is B" << endl;
            }
            else if (average >= 79 && average <= 70)
            {
                cout << "Letter grade is C" << endl;
            }
            else if (average >= 79 && average <= 60)
            {
                cout << "Letter grade is D" << endl;
            }
            else
            {
                cout << "Letter grade is F!" << endl;
            }
            
        }// End loop grade.
        
        // Loop for class average.
        for (int i = 0; i != 5; i++)
        {
            class_average = sum_of_test_scores / 5.0;
            
        }
        cout << "The class average is: " << class_average << endl;
        
        // Close the file.
        inputFile.close();
    
        // releasing memory block on the heap.
        delete [] arrayNames;
        arrayNames = 0;
        delete [] arrayID;
        arrayID = 0;
        delete [] arrayAverage;
        arrayAverage = 0;
        delete [] arrayLetterGrade;
        arrayLetterGrade = 0;
    }
    return 0;
}// End Code. 



Is the file good? --> true

Amy Adams
10111
97
86
78
95
I have read 1 record/s

Ben Barr
20222
89
81
73
87
I have read 2 record/s

Carla Carr
30333
79
71
63
77
I have read 3 record/s

Don Davis
40444
69
62
58
67
I have read 4 record/s

Edna Eaton
50555
63
51
62
48
I have read 5 record/s

Amy Adams
  97 86 78 95 

Ben Barr
  89 81 73 87 

Carla Carr
  79 71 63 77 

Don Davis
  69 62 58 67 

Edna Eaton
  63 51 62 48 

The average is: 291.2
invalid average for grade please try again.
invalid average for grade please try again.
invalid average for grade please try again.
invalid average for grade please try again.
invalid average for grade please try again.
The class average is: 291.2
Last edited on
Line 88: Your loop is summing the scores for ALL the students.
Line 96: You then use this sum to calculate an average for ALL the students.
Line 100: You then use this average for ALL the students to determine a grade.

As your program is structured, you need sum_of_test_scores and average to be arrays. i.e. One occurrance for each strudent. You allocate arrayAverage, but don't use it.

Since students is a const, there is no reason to be allocating arrayID, arrayNames, arrayAverage as dynamic arrays.

You can also reduce the number of loops in your program.

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
//  main.cpp
//  Program 8
//  Created by William Blake Harp on 7/16/14.

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

using namespace std;

char calculate_grade (int average)
{	if (average > 100)
    {	cout << "invalid average for grade please try again." << endl;
		return ' ';
    }
    if (average >= 90 && average <= 100)
        return 'A';
	if (average >= 89 && average <= 80)
		return 'B';
	if (average >= 79 && average <= 70)
		return 'C';
    if (average >= 79 && average <= 60)
		return 'D';
	return 'F';
}

int main()
{	double class_average = 0;
	int class_sum = 0;
    string str;

    const int STUDENTS = 5;
    const int TESTS = 4;
	struct 
	{	string name;
		int id;
		int sum;
		int average;
		char grade;
		int scores[TESTS];
	} student [STUDENTS];

    ifstream inputFile;

    // Open the file.
    inputFile.open("Student Data.txt");
    if (! inputFile)
	{	cout << "Can't open the file!" << endl;
		return 1; 
	}
	//	Input loop
    for ( int i=0; i<STUDENTS; i++)
    {	// read name.
        getline(inputFile, student[i].name);
        cout << student[i].name << endl;  
        
		// read student id.
        inputFile >> student[i].id;
        cout << student[i].id <<endl;
            
        // read four(4) scores.
        for (int j=0; j<TESTS; j++)
        {	inputFile >> student[i].scores[j];
            cout << student[i].scores[j] << endl;
        }
                       
        // consume '\n' char (Use getline for mac/Xcode!!!).
        getline (inputFile, str);              
    }	// end read loop.
    
    //	Processing loop
    for (int i=0; i<STUDENTS; i++)
    {	cout << student[i].name << "  ";           
        for (int j=0; j<TESTS; j++)
        {	cout << student[i].scores[j] << " ";
        }
        cout << endl << endl;
    	student[i].sum = 0;
        for (int j=0; j<TESTS; j++)
        {	student[i].sum += student[i].scores[j];
        }
		student[i].average = student[i].sum / TESTS;
        cout << "The average for " << student[i].name << " is " << student[i].average << endl;
		student[i].grade = calculate_grade (student[i].average);	// Geting a letter grade.
 		cout << "Letter grade is: " << student[i].grade << endl;            
		class_sum += student[i].sum;
    }
	class_average = (double)class_sum / (double)STUDENTS;
    cout << "The class average is: " << class_average << endl;
        
    // Close the file.
    inputFile.close();   
	return 0;
}// End Code.  


edit: Sorry, just reread your first post. Looks like your assignment dictated dynamic arrays on the heap.
Last edited on
@ Abstraction Anon

That done not really help me that much :) I know how to move every thing in the loops and stuff and get everything to out put like I what what I need help on is how would I take my program and get the average and the class average. Because as of right now 1 they are the same and 2) They are both wrong. Once I see how I would do that I can manipulate my program to do what I need. So any suggestions on that would be very helpful! Thank you so much!
Read my comments above about lines 88, 96 and 100.

Per my edit, I didn't realize you were required to use dynamic arrays. However, you should look at my posted code as to where it is using subscripted items and your code is not. e.g. a sum per student, an average per student, etc.
Topic archived. No new replies allowed.
Pages: 12