help with using datafiles in arrays

Pages: 12
I am so confused on how I am supposed to write this program. The datafile "scores.dat" contains 1000 individual student scores (integers in the range of 0 to 100) for a campus wide assessment instrument. It should read the file and load the data into an array. It should then process the array and produce the following statistics: average score, minimum score, maximum score, and count and report the number of "Excellent" (95-100), "Satisfactory" (80-94), "Normal" (50-79), and "Needs Improvement" (0-49) scores. Any help would be appreciated!
Last edited on
I assume each integer in its own line.
1
2
3
4
5
6
7
std::ifstream inp("scores.dat");
int scores[1000];
int x;
int i = 0;
while(inp >> x && i < 1000) {
    scores[i++] = x;
}

Now you have an array with scores. You can iterate over it and calculate all data you need. (actually you can optimize everything to not use an array at all)
Last edited on
Im sorry but I still am unsure how to get started
what part of the code you didn't understand? give us a clue
Like I don't understand any.. I don't know how to get started on this program at all.. and I don't know how to enter the datafile correctly
Last edited on
Do you know the basics or at least the needed fundmentals for doing this like files i/o, arrays, control statments...et
Well somewhat I know the basics. I was hoping someone could just walk me through the steps of putting this program together.
If you know the basics, then you should be able to start. The intention is most likely that you do learn by doing. Please tell, that you know Hello World?


PS. std::vector, std::accumulate, std::count_if, std::max_element, std::min_element. Probably something that you are not supposed use, because they make it all to easy and don't teach to think.
Cluterbug,

The forum definitely needs more information to help you out. Particularly, whether or not you know how to use input/output file streams (ifstream/ofstream).

I'm not a pro, but for your particular problem, I'd recommend:

1) create a structure (or class) to handle the data for each student.

1
2
3
4
5
6
7
8
9
10
11
12
struct student
{
     string studentName;
     int minScore;
     int maxScore;
     int avgScore;
     int scoreCount;
     int numExcellent;
     int numSatisfactory;
     int numNormal;
     int numNeedsImprove;
};


The benefit of using classes here is that you can add member function(s) that return the excellent, satisfactory, normal, needs improvement statistics you are looking for; as well as the calculate the avgScore and other needed information. I don't have enough time to build a class but you get the drift.

2) You'll then need to create an array of this structure (or object), to hold the information for each student. You can of course dynamically allocate this if need be.

 
student allStudents[15];


3) Finally, you'll have to create an ifstream object and get the information needed from the file. We would need much more information about the format of your data file, but assuming it's a .txt filel, it would be something like:

1
2
ifstream fin("MyText.txt");
while (fin >> allStudent.studentName >> ',  ' >> allStudent.minScore......);
Last edited on
Ok, so I tried to put some of it together and I don't think its working out right. Also I put in the forum that the datafile "scores.dat" contains 1000 individual student scores (integers in the range of 0 to 100).

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>
using namespace std;

const int num = 15;


int main()
{
       struct student
{

     double allStudent[num];
     string studentName;
     int minScore;
     int maxScore;
     int avgScore;
     int scoreCount;
     int numExcellent;
     int numSatisfactory;
     int numNormal;
     int numNeedsImprove;
}

	ifstream fin;("Mytext.txt");
         while (fin >> allStudent.studentName >> ",  " >> allStudent.minScore);
{

}



	return 0;
}
@todricos
in your last point you made a mistake you wrote

while(fin >> allStudentName >> ','...) !
You get data from fin and put it in a ',' which is illegal.
cluterbug what is your exactly file format i mean how is the 1000 data is written if the dat file
I don't see how it matters.. This program should be able to just count by itself and everything after you input it.. Its just a white screen and has 1000 numbers between 0-100 in it.

Last edited on
@todricos:
1. That struct does not match at all the "The datafile contains N individual student scores (integers in the range of 0 to 100)" description. AkramIzzeldin asks the exact format, which I bet to be closer to what MiiNiPaa assumed; a thousand numbers and nothing more.

2. student allStudents[15]; is static allocation, not dynamic. For dynamic allocation, one would look at the standard library containers.
1
2
3
4
5
6
std::vector<int> bar;
bar.reserve( 1000 );
int score = 0;
..
// within loop
  bar.push_back( score );



@Cluterburg:
Structs/classes are not defined inside main(). Const 'num' can be inside main().

You now have a loop that repeatedly overwrites the value of same variable(s) from input. It should store each value to a different memory location -- "next slot on array". MiiNiPaa's loop has one example. vector::push_back() is bit different.
So I don't understand what to do next..
The assignment was quite clear:
1. Form a list (array) of numbers.
2. Look at the numbers on the list to count something.
3. Show results.

MiiNiPaa's code does the first step. 'scores' is the list. It contains 'i' numbers.

Second step is again iteration over list. You must have some variables to collect results to. For example, increase 'numExcellent' by one every time you look at a number in the list that is within limits of "excellent".
OK i will assume that the dat file is written with only the degrees seprated by a space cause you dont need the students names.
First you will make an array of ints with size 1000, then you will open the file for reading and make a for loop counts to 1000 in each time it reads from the file to the array element i, now you have the scores in the array the only thing left is calculating the average score (sum of the elements of the array / 1000.0), the lowest score (comparing every element until findin the lowest one), the highest score (test each element until finding the highest) and the exellent, weak... Scores (testing elements and counting the exellent scores, weak..).
Try this and show us if anything went wrong
I was bored:
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
#include <iostream>
#include <fstream>
#include <iterator>
#include <vector>
#include <algorithm>

int main()
{
    std::ifstream inp("scores.dat");
    std::vector<int> scores;
    std::copy(std::istream_iterator<int>(inp), std::istream_iterator<int>(),
              std::back_inserter(scores));
    auto minmax(std::minmax_element(std::begin(scores), std::end(scores)));
    int excellent(0), satisfactory(0), normal(0), needImprovement(0);
    double average = std::accumulate(std::begin(scores), std::end(scores), 0,
                                     [&](int x, int y)
                                     {        if (y < 50) ++needImprovement;
                                         else if (y < 80) ++normal;
                                         else if (y < 95) ++satisfactory;
                                         else             ++excellent;
                                         return x + y; });
    average /= scores.size();
    std::cout << "Maximum score is: " << *(minmax.second) << "\n" <<
                 "Minimum score is: " << *(minmax.first) << "\n" <<
                 "Average score is: " << average << "\n" <<
                 "There is:\n" << excellent << " Excellent scores\n" <<
                 satisfactory << " Satisfactory scores\n" << normal <<
                 " Normal scores\n" << needImprovement << " Needs improvement!";
}
However it is incomplete: there is some lines which still can be compiled be non C++11 compliant compiler :\
Last edited on
So in line 15 where it says accumulate it says that 'accumulate' : is not a member of 'std' and in line 17 the open bracket says a lambda that has been specified to have a void return type cannot return a value.

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
#include <iostream>
#include <fstream>
#include <iterator>
#include <vector>
#include <algorithm>

int main()
{
    std::ifstream inp("scores.txt");
    std::vector<int> scores;
    std::copy(std::istream_iterator<int>(inp), std::istream_iterator<int>(),
              std::back_inserter(scores));
    auto minmax(std::minmax_element(std::begin(scores), std::end(scores)));
    int excellent(0), satisfactory(0), normal(0), needImprovement(0);
    double average = std::accumulate(std::begin(scores), std::end(scores), 0,
                                     [&](int x, int y)
                                     {        if (y < 50) ++needImprovement;
                                         else if (y < 80) ++normal;
                                         else if (y < 95) ++satisfactory;
                                         else             ++excellent;
                                         return x + y; });
    average /= scores.size();
    std::cout << "Maximum score is: " << *(minmax.second) << "\n" <<
                 "Minimum score is: " << *(minmax.first) << "\n" <<
                 "Average score is: " << average << "\n" <<
                 "There is:\n" << excellent << " Excellent scores\n" <<
                 satisfactory << " Satisfactory scores\n" << normal <<
                 " Normal scores\n" << needImprovement << " Needs improvement!";
}
Last edited on
Update your compiler. accumulate was member of std since forever (I believe from C++03)
It should deduce return type of lambda too. But you can just change line 16 to [&](int x, int y) -> int
Pages: 12