Topics to Cover

Structs that contain arrays

Suppose we have a file namedgrades.txt, which contains student grade information. The file looks like this:
11 students
10 homeworks
Adams	58	96	65	72	93	67	59	74	95	56
Brown	96	67	56	74	94	100	98	68	95	65
 ...  
telling us initially how many students we have, how many homework scores for each student, and then listing all the student names followed by their homework scores.

Now, I'd like to write a program that works as follows:

Now, assuming there are Ns students and Nh homeworks, the natural way for us to think of this is to say "I'd like to have an array of Ns objects of type Student." We know how to construct a struct Student, so that's no problem, but what data members would we need to store this student data? We'd need a string to store the name, and we'd need ... well, we'd need an array of Nh ints to store the homework grades. In other words, we'd need a data member of type int*.


struct Sudent
{
  string name;
  int* hw;
};

Packaged up this way, an object of type Student representing the student "Brown" from above would look like the picture above. Now, the question is, if variable S is the Student object from the picture, what expression would give me the value of the homework assignment with index 2? Well, S.hw is the name of the pointer to the array of grades, so I just need to subscript it with a 2: S.hw[2]! I might be tempted at this point to look back at my original problem and say that I'll create my storage for all this student/grade data with:
Student* stu = new Student[Ns];
Quick check

Consider the code on the left.

  1. What is the type of stu?
  2. What is the type of stu[j]?
  3. What is the type of stu[j].hw?
  4. What is the type of stu[j].hw[0]?
Answers are given below (drag your mouse):
1. Student*  2. Student  3. int*  4. int
It's true that stu is now an array containing Ns object of type Student, but remember that each Student object has data member hw, which is just an uninitialized pointer at this juncture. We need to go back and allocate homework-grade arrays for each Student object in the array. So creating our storage really looks like this:

Student* stu = new Student[Ns];
for(int j = 0; j < Ns; j++)
  stu[j].hw = new int[Nh];
At this point, writing the program is not very new for us: Here's my solution. All I did was use the top-down design that we've seen so many times. I simply wrote the main function the way I wished I could, and created the structs and functions that made writing main that way possible.

What assignment and pass-by-value mean with structs

Composition of structs

Imagine a scenario in which we are performing experiments with cockroaches. We'll suppose we get data readings for other roaches that give us a time in [hh:mm:ss] format, and a position in (x,y) coordinates. For example, trial.txt. We want the user to be able to enter a time in [hh:mm:ss] format and we'll tell him where the roach is (i.e. en route between which two points).

We've dealt with points before, and we will again, so let's go ahead and give the basic struct definition & function prototypes for points:


//--- POINT ---------------------------------//
struct point
{
  double x, y;
};
istream& operator >> (istream& is, point& p);
ostream& operator << (ostream& os, point p);
Now, while we may not have dealt with times in hh:mm:ss for a while, it is not unlikely we'll have to deal with such things again. Therefore, it is natural to give a struct definition and some prototypes for an hhmmss struct:

//--- TIME IN HH:MM:SS ----------------------//
struct hhmmss
{
  int h,m,s;
};
istream& operator >> (istream& is, hhmmss& t);
bool operator < (hhmmss a, hhmmss b);
Now, a data reading consists of a time and a position, so it might be nice to have a datum struct that records a single data reading. It'd look something like this

struct datum
{
  point position;
  hhmmss time;
};
... and I'd probably want an operator istream& operator >>(istream& is, datum& d); to read in such objects.

Mandatory Practice Problem

Recall that trial.txt contains the following data:
8 data listings
{[02:00:23],(6.67,0.03)}
{[02:12:54],(4.03,0.53)}
{[02:23:12],(3.44,0.42)}
{[02:29:01],(3.08,0.61)}
{[02:44:51],(2.05,4.70)}
{[02:46:20],(1.98,4.80)}
{[02:57:43],(2.01,5.12)}
{[03:01:23],(2.24,5.43)}
Complete this program. The program first reads trial.txt. When the user enters a time in [hh:mm:ss] format, the program tells him where the roach is (i.e. en route between which two points). Here are the sample runs.
$ ./a.out
Enter a time: [01:00:20]
This was before the first sighting at (6.67,0.03)

$ ./a.out
Enter a time: [02:40:10]
The roach was somewhere between (3.08,0.61) and (2.05,4.7)

$ ./a.out
Enter a time: [04:00:00]
This was after the last sighting at (2.24,5.43)
Solution: here.

Other Practice Problems

  1. In HTML, colors are specified by a "number". for example, yellow is specified by the "number" #FFFF00. And you can color words using this. For example, if I want to Write "Hello", in HTML (i.e. Hello with a yellow H on the front), I use the following HTML:
    <font color="#FFFF00">H</font>ello
    The file colors.txt contains a list of number/names. Write a program that reads in this file, allows the user to enter colors and words, and finally produces an HTML file that writes those words in those colors. Example:
    Enter color and word, or quit: Blue  Somewhere
    Enter color and word, or quit: Green over
    Enter color and word, or quit: Aquamarine the
    Enter color and word, or quit: Gold rainbow
    Enter color and word, or quit: quit 
    With this, your program should create an html file like this.
  2. Write a program that reads in points from the file points.txt and writes out the lower left and upper right coordinates of the smallest rectangle containing all the points from the file. Here's My Solution.