Here are tips on implementing the histogram project. They focus on
the use of C-style strings to print labels on the histogram's axes.
1. Print labels on the histogram's axes:
It's nice to print labels on coordinate axes for the histogram. For
example, we might label the x-axis with characters and the y-axis with
counts. So the histogram below says indicates that there are 40
occurrences of ' ' (SPACE; notice that the first bar seems to have no
label; really it's a space, which is invisible), 20 occurrences of
'e', 15 of 't', and 10 each of 'a' and 'm'.
... |
|
|
50 |
|
40 | |
| |
30 | |
| |
20 | | |
| | | |
10 | | | | | |
|__|__|__|__|__|_____
0 / e t a m ...
2. C-style strings:
We could use BGI's outtextxy() function to print these labels. Here
is its prototype:
void outtextxy(int x, int y, char *textstring);
The type "char *" means "pointer to a character"; we haven't yet
discussed pointers. But in a function prototype, a pointer and an
array of unspecified size are the same thing. So we can read this
prototype as if "textstring" were an array:
void outtextxy(int x, int y, char textstring[]);
An array of characters is a C-style string. (We usually prefer the
C++ "string" type, but we frequently need C-style strings to use C
functions which haven't been updated to C++.)
We've already seen that we can initialize an array of characters with
a string literal, as in this declaration:
char in_file[40] = "message.dat";
In a statement like "cout << in_file << endl;", how does the compiler
know where the string "message.dat" ends? The C convention is that
each C-style string is terminated by a zero byte. A zero byte is the
ASCII value 0; it is not the same as the character '0', whose ASCII
value is 48. So these are the values in the in_file[] array:
in_file[0] == 'm' // ASCII value 109
in_file[1] == 'e' // ASCII value 101
in_file[2] == 's' // ASCII value 115
...
in_file[11] == 't' // ASCII value 116
in_file[12] == 0 // ASCII value zero, not character '0'
// Note that in_file[13] through in_file[40 - 1] are uninitialized
// garbage.
3. Printing numbers on the y-axis using "itoa()":
In order to print numeric labels on the histogram's y-axis, we need to
make a C-style string which corresponds to an integer. The standard
library function "itoa()", whose name means "integer to ASCII", does
this for us. Its prototype is
// itoa() sets the passed-in character array "s[]" to a C-style
// string containing the ASCII representation of the integer "i",
// using base "base" numbers. ("base" is typically 10, but it
// might be 2 for binary numbers, etc.) It returns s.
char * itoa(int i, char s[], int base);
Suppose we have these declarations:
char num_string[20];
int n = 12;
int base = 10;
Then the function call below sets num_string[] to "12". That is, it
sets num_string[0] to '1', num_string[1] to '2', and num_string[2] to
0 (not '0') to terminate the string.
itoa(n, num_string, base);
We can ignore the return value, or use it in a statement like this:
cout << itoa(n, num_string, base); << endl;
So to print y-axis labels, we could use code like this:
const int MAX_X = 640;
const int MAX_Y = 480;
const int MARGIN = 50;
const int MAX_COUNT = 100;
settextstyle(DEFAULT_FONT, HORIZ_DIR, 1);
for (int i = 0; i < MAX_COUNT; i += 10)
{
int x = MARGIN; // Set (x, y) to location of label.
int y = (MAX_Y - MARGIN) - (10 + 3 * i);
char num_string[20];
outtextxy(x, y, itoa(i, num_string, 10));
}
4. Printing characters on the x-axis by manually forming a C string:
In order to print character labels on the histogram's x-axis, we need
to make a C-style string which corresponds to a character. To do
this, we can assign the string's [0] element to the character we need,
and then terminate the string by assigning the string's [1] element to
zero. For example,
char char_string[2];
char_string[0] = 'e';
char_string[1] = 0;
Alternatively, since 'e' has ASCII value 101, we could use
char_string[0] = 101; // ASCII value of 'e' (using 101 is poor style)
char_string[1] = 0;
So this loop prints the first five letters ('a' through 'e') to a BGI
screen:
for (int i = 0; i < 5; i++)
{
char char_string[2];
int x = MARGIN + (MARGIN + 20 * i); // Set (x, y) to location of label.
int y = MAX_Y - MARGIN;
// When i == 0, set char_string[0] to 'a'. When i == 1, set
// it to 'a' + 1, which is 'b'; etc.
char_string[0] = 'a' + i;
char_string[1] = 0; // zero byte
outtextxy(x, y, char_string);
}
5. Note that the preceeding code examples are intended only to show
how to print integers and characters in the BGI screen, not to solve
part of the histogram project.