help with using datafiles in arrays

Pages: 12
Apr 22, 2013 at 6:20pm
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 Apr 22, 2013 at 6:30pm
Apr 22, 2013 at 7:18pm
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 Apr 22, 2013 at 7:18pm
Apr 22, 2013 at 8:14pm
Im sorry but I still am unsure how to get started
Apr 22, 2013 at 8:43pm
what part of the code you didn't understand? give us a clue
Apr 22, 2013 at 9:50pm
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 Apr 22, 2013 at 9:55pm
Apr 23, 2013 at 5:00am
Do you know the basics or at least the needed fundmentals for doing this like files i/o, arrays, control statments...et
Apr 23, 2013 at 1:04pm
Well somewhat I know the basics. I was hoping someone could just walk me through the steps of putting this program together.
Apr 23, 2013 at 1:25pm
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.
Apr 23, 2013 at 1:49pm
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 Apr 23, 2013 at 1:54pm
Apr 23, 2013 at 2:33pm
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;
}
Apr 23, 2013 at 2:45pm
@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.
Apr 23, 2013 at 2:48pm
cluterbug what is your exactly file format i mean how is the 1000 data is written if the dat file
Apr 23, 2013 at 3:04pm
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 Apr 23, 2013 at 3:05pm
Apr 23, 2013 at 3:11pm
@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.
Apr 23, 2013 at 9:19pm
So I don't understand what to do next..
Apr 24, 2013 at 5:13am
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".
Apr 24, 2013 at 6:45am
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
Apr 24, 2013 at 10:48am
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 Apr 24, 2013 at 11:27am
Apr 24, 2013 at 2:45pm
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 Apr 24, 2013 at 2:47pm
Apr 24, 2013 at 3:12pm
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