Program crash

Hi there, I'm having trouble with my code. The program is supposed to take in a file and read in the values, the students names and their grades. However, the program always crashes when I insert the file. Is it a size related issue? or something else?


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
  #include "students.h"


#include <string>

students curve(students, int);

int main(int argc, char** argv)
{
  int size = 0;
  int counter = 0;
  char option;
  students myclass;
  fstream inFile;
  const char* filename="";
	filename = argv[1];
	char* newfilename;
  do
	{
	inFile.open(filename);
	if(!(inFile.is_open()))
	{
		cout<<"File not found. Please type in a correct file name"<<endl;
		cin >> newfilename;
		inFile.open(newfilename);
	}
	}while(!(inFile.is_open()));
	
    inFile >> size;
    inFile.ignore();
    while(!inFile.eof())
    {
      getline(inFile, myclass.student[counter].name);
      for(int i = 0; i<size; i++)
      {
        inFile >> myclass.student[counter].grades.array[i];
        myclass.student[counter].grades.valuesinArray++;
      }
      inFile.ignore();
      counter++;
      myclass.current++;
      if (counter >= myclass.maximum)
      {
        myclass.maximum * 2;
      }
    }
  
  inFile.close();


  counter = 0;
  int numOfTests = myclass.student[0].grades.valuesinArray;
  float average[numOfTests];
  float studentAverage[myclass.current];

  for(int i=0; i<numOfTests; i++)
  {
    for(int j=0; j<myclass.current; j++)
    {
      average[i]+= myclass.student[j].grades.array[i];
    }
    average[i] = average[i] / numOfTests;
    cout << "The grades on test " << i + 1 << " average to a " << average[i] << ". ";
    if(average[i] < 70)
    {
      cout << "Do you want to curve?";
      cin >> option;
      if(option == 'y')
      {
        myclass = curve(myclass, i);
      }
    }
  }

  for(int i = 0; i < myclass.current; i++) //find student final averages
  {
    for(int j = 0; j < numOfTests; j++)
    {
      studentAverage[i] += myclass.student[i].grades.array[j];
    }
    studentAverage[i] = studentAverage[i] / numOfTests;
  }


  return 0;
};


students curve(students myclass, int test)
{
  int max = 0;
  for(int i = 0; i < myclass.current; i++)
  {
    if(max < myclass.student[i].grades.array[test])
    {
      max =  myclass.student[i].grades.array[test];
    }
  }
  float curve = 100 - max;

  for(int i = 0; i < myclass.current; i++)
  {
    myclass.student[i].grades.array[test] += curve;
  }

  return myclass;
}
.h file

#ifndef STUDENTS_H
#define STUDENTS_H

#include <string>
#include <iostream>
#include <fstream>
#include <iomanip>
using namespace std;

struct Array
{
  float array[20]; //Place holder of 20
  int valuesinArray; //Number of Tests
  int secondMax;
};

struct student
{
  string name;
  Array grades;
};

struct students
{
  student student[];
  int current = 0;
  int maximum = 2;
};




#endif




Here is the text file:

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

5
Holly Johnson
83
47
93
45
78
Robert Smith
83
72
55
66
58
Fred Mercury
47
57
59
94
51
Robert Plant
76
83
58
79
85
Cy Curnin
75
90
42
96
85
Paul Westerberg
96
73
58
93
70
Ian Curtis
81
56
47
87
97
Paul Weller
70
46
92
82
77
Roland Gift
100
65
70
83
75
Ian McCulloch
58
49
91
91
87

It doesn't compile.

What is this line supposed to do?
student student[];
Hello Drake5006,

With out digging into the code what jumped out at first it the use of the "#include" files in the header file. This is not the place to put "#include" files they belong in the ".cpp"files. Second is "using namespace std;" this should never be in a header file. for a better explanation read this:http://www.lonecpluspluscoder.com/2012/09/22/i-dont-want-to-see-another-using-namespace-xxx-in-a-header-file-ever-again/

As lastchance said get to program to compile first and if not include the complete error message of what you do not understand.

Thank you for the input file that really does help.

Andy
Hello Drake5006,

As I started working on your program I found some errors that need to be fixed.

The lines 53 and 54:
1
2
float average[numOfTests];
float studentAverage[myclass.current];

You can not do this. What is between the []s must either be a constant number like "10" or a variable defined as a constant. To use what you have yu would have to create a dynamic array.

It is better to use "double" over "float". "double"s have greater precision and store the numbers better. If your numbers to the right of the decimal point are short the "float" may work.

As lastchance pointed out you have the line in the header file student student[];. What is missing between the []s is a size. creating an empty array is not allowed.

When I write a class, struct or function I like to use a capital letter to start the name. Looking at the code in the above paragraph it looks like two variable names. The IDE and compiler may be able to tell the difference, but it can be confusing at first glance. This reads better and makes it easier to tell what the struct is:
Student student[10];.

While I am here try to avoid using the name "Array" and especially "array" and if you use using namespace std; this will avoid any problems. If you have no restrictions a "std::vector" would work better than the arrays that you are trying to use. First you would not have to state a size of the vector.

You have the line: myclass.maximum * 2;. This has no effect because the multiplication is not stored anywhere. "myclass" is misleading because it is a struct not a class. A name that has some meaning would help. And writing the name as "myClass" is the more acceptable way to write a variable name made up of more than one word.

Line 96. And this is only a warning, but "max" is defined as an "int" and what is on the rhs of the '=' eventually gets to a "float". You can store a "float" in an "int", but you will loose anything to the right of the decimal point this may not be what you want.

Line 99. You define "cure" as a "float", but use two "int"s to initialize this with a value. This produces a warning,but it is not a big problem unless you need a decimal value.

Back to the beginning of main line 17 I changed "char*" to "std::string" to eliminate an error. In this case a "std:;string" will work fine.

Now that the program compiles and runs I can start testing.

Hope that helps,

Andy
Thanks, I'll fix those errors right away!
Hello Drake5006,

While testing the program I realized line 31.

while(!inFile.eof())

I do not know why people teach this. This is a bad idea as it does not work the way you think it will. Generally by the time the while condition determines that "eof" has been reached you will have processed the last read twice and wondering why it shows up twice.

What happens is the while condition is checked and “eof” has not been set yet. After entering the while loop you read the last line or bit of information from the file process the information reach the bottom of the while loop. At this point “eof” has not been set yet and you return to the while condition which is still good. After entering the loop you try to read from the file, but now there is nothing left to read and “eof” is set, but you do nothing at this point to deal with the “eof” condition. So you process what information is in the variables from the last read before returning to the while condition where it finally detects the “eof”, but you have processed the last good read twice unless you have cleared the variables at the end of the while loop in which case the last process will be blank.
A more acceptable way of using the while loop is:

1
2
3
4
5
while (infile >> someVariable)
{
    infile >> additionalVariables;
    //  Additional code.
}


In the above example you can set up the while condition to read one variable, two or more variables or use “std::getline(?, str)” where ? could be from “std::cin” or from a file stream and “str” represents any “std::string” variable.

In your case the while condition would be: while (std::getline(inFile, myclass.student[counter].name))

In the header file I had to give the arrays an actual number for the size of the array. In main I defined:
constexpr std::size_t MAXSIZE{ 10 }; just for something to work with for now. If you know about "std::vector"s I would replace the arrays with vectors much easier to use and you do not have to define a size to start with. The two lines that would use this are defined as:
1
2
double average[MAXSIZE];
double studentAverage[MAXSIZE];


I have the program to the point of reading and storing the data, but it will be tomorrow for me before I check out the rest of the program.

Hope that helps,

Andy
Topic archived. No new replies allowed.