Read uneven records from file in to class

I am trying to write a program to solve this problem.


The following shows a sample input file for class called Training. How can I read these uneven records in to class?



2 //------>//this is number of sessions for training ID T1101
T1101
Basic Web Programming Course
1/12/2013
8:00 – 17:00
250.00
2
871012-10-5543 //---->>Participant ID and namess in training T2100
Tony
Stark
700607-10-6231
Bruce
Banner
T2100
Mobile Application Development
20/1/2014 – 22/1/2014
9:00 – 17:00
1500.00
3
600304-06-5121
Clark
Kent
990126-10-1727
Peter
Parker
680501-10-5696
Bruce
Wayne

An array of Training (based on the number read from the file) should be created dynamically then load all the details into each Training object.
Last edited on
It's pretty common to store data like this. You can read it into a vector like this:
1
2
3
4
5
6
7
8
9
10
11
12
class Stuff;
...
bool readStuffArray(vector<Stuff> &vec, istream &is)
{
    unsigned num;
    is >> num;            // get the number to read
    vec.resize(num);   // resize vec. Now it has num items.
    for (int i=0; i< num; ++i) {   // read num items.
        is >> vec[i];
    }
    return is;
}

We havent learnt vector..we are only supposed to use basic class which makes it harder
Last edited on
I am doing this but not working:

while !EOF:
peek character;
if peek==digit
read session_total;
create instances of this session[session_total];
if character is a digit and equals 16 digits:
read in mykad;
read in names;
peek character;
while character is a digit and equals 16 digits:
read in mykad;
read in names;
peek character;
read in training id;
read in date, time, charges;
else:
read in training id;
read in date, time, charges;
The data follows a pretty rigid format. Since everything is on a single line, that helps a lot. Still, your professor's a jerk to give you a format that requires delayed inspection to figure out what to do with the data.

The main problem is that the format makes you read a couple of lines before you can identify what kind of record it is.

1
2
3
4
5
6
7
8
Training lecture:
<number of sessions>
<training session ID>
<session name>
<session date> ['-' <session date>]
<start time> '-' <stop time>
<cost>
Participant list:
<number of participants in this list>

<participant ID>
<participant given name>
<participant surname>

...

See how you must read at least the first line's number and then the second line's ID before you can identify what the remainder of the record is going to look like?

There are several ways to handle this kind of input, some more sophisticated (and maintainable) than others, but for your purposes (schoolwork, right?) a simple loop with some nested loops might work best.

The following pseudocode does not include error handling, but you should add it after every attempt to read a line of data from the file. Something like

if (!getline( fin, s )) throw "fooey!";

might be what is best for this kind of problem.

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
try {
  while (getline( fin, s ))
  {
    int n = string_to <int> ( s );
    if (!getline( fin, s )) throw "unexpected EOF";
    switch (identify( s ))
    {
      case TRAINING_ID:
      {
        read the remaining training session data
        add the new training session record (including n and the id) to your array of training sessions
        (remember to stop with an error [like throw "fooey!"] if getline( fin, s ) doesn't work
         at any time)
      }
      break;

      case PARTICIPANT_ID:
      {
        read the remaining data from the first participant and add it to the array of participants
        for the remaining (n-1) participants, read their data from file and add them to the array of participants
        (use the same error handling in this block of code too)
      }
      break;

    default: throw "halting; unknown data!";
  }
}
catch (...)
{
  (this is where you deal with any input error)
  return the data you've got, or an error, or both, whatever is appropriate.
}
return the data you've got, all ok. 

Hope this helps.

Oh, a helper function:
1
2
3
4
5
6
7
8
9
template <typename T>
T string_to( const std::string& s )
{
  T result;
  istringstream ss( s );
  ss >> result;
  if (!ss.eof()) throw "invalid conversion";
  return result;
}
We havent learnt vector..we are only supposed to use basic class which makes it harder

Then just keep track of the number of items and allocate an array on the heap:
Session *sessions = new Session[number_of_sessions];
What does this session do? For example for the first records what would this session do? I am confused ...first record got 2 as number so it would open two sessions instances but why I need two session instances?
Thanks duos, I will give it a try
Topic archived. No new replies allowed.