Study this code for a minute before continuing. You may even be able to guess at some of the newer features and do a hand simulation.
#include <iostream> int main() { int c; while ((c = cin.get() ) != EOF) if (c == '!' || c == '@') if (c == '!') cout.put('X'); else cout.put('x'); else cout.put(char(c)); return 0; }
Now a line by line discussion.
#include <iostream> int main() {
Nothing new here. But this:
int c;
Why are we using an int datatype if we are doing character input? Well, in short, a character is nothing but an integer (ASCII number). Just bear with me a moment.
This line, we will have to break down a bit:
while ((c = cin.get() ) != EOF)
First, let's look at the innermost item:
cin.get()
Here you are calling a function cin.get() of the object cin (which you have already used. This function grabs the first thing in queue in the keyboard buffer.
Then we take what is returned from the function and put it into the variable c, in an integer form.
c = cin.get()
Enclosing that in parentheses makes it the first item to be evaluated. Now we evaluate that statement against the End Of File character (EOF):
( c = cin.get() ) != EOF ;
If it is not equal to that character, then the while loop begins. The EOF character in BeOS (and incidently, UNIX and most other OSs) is made by pressing the ctrl-key and d at the same time. In DOS-based systems, the EOF character is ctrl-z. What this means is if the user enters ctrl-d, the while loop concludes and, consequently, the program ends.
Now remember, the while structure syntax is:
while (conditional expression) // where the conditional expression is (c=cin.get()) != EOF [statement]
which looks like this:
while ( (c = cin.get() ) != EOF ) if (c == '!' || c == '@') if (c == '!') cout.put('X'); else cout.put('x'); else cout.put(char(c));
Where is the curly-braces, you ask? They are not necessary here. The if / else statement is only one statement, and the if / else embedded within is only one statement. Making one large, legal statement. If it makes you feel better, here is the same thing with curly-braces and comments off to the side:
while ( (c = cin.get() ) != EOF ) { // Begin while if (c == '!' || c == '@') { // Begin first if if (c == '!') { // Begin nested if cout.put('X'); } // End nested if else cout.put('x'); } // End first if else cout.put(char(c)); } // End while
[Begin a style rant]
Pay no attention to the code we haven't covered yet, this is all cosmetics right now
First, can you see now how this is just one statement? Also notice how I indented everything as it nested further within structures, this is a matter of good, easy to read style. You can also place the opening curly-braces in different locations.
while ( (c = cin.get() ) != EOF ) { // Begin while if (c == '!' || c == '@') { // Begin first if if (c == '!') { // Begin nested if cout.put('X'); } // End nested if else cout.put('x'); } // End first if else cout.put(char(c)); } // End while
This is also a matter of style. The practice of indenting closing curly-braces at the same level of indentation with the opening structures is also common, but a still just a matter of style.
I also compressed (removed extra lines) from this fragment. How much you space things out to make them easier to read is up to your own style, remember, whitespace characters are not seen by the compiler. Look at these two fragments and decide which is easier to read, this one:
while ( (c = cin.get() ) != EOF ) { // Begin while if (c == '!' || c == '@') { // Begin first if if (c == '!') { // Begin nested if cout.put('X');} // End nested if else cout.put('x');} // End first if else cout.put(char(c));} // End while
or this one:
while ( (c = cin.get() ) != EOF ) { // Begin while if (c == '!' || c == '@') { // Begin first if if (c == '!') { // Begin nested if cout.put('X'); } // End nested if else cout.put('x'); } // End first if else cout.put(char(c)); } // End while
It's all up to your tastes, but try to keep it clean.
[End style rant]
Now back to the program. In summary: So far, we have determined that the user will input a single character from the keyboard. The cin.get() function will grab the first one in queue in the keyboard buffer for use. The user can enter up to as many characters as once as they like, but cin.get() will only grab the first one in queue, hence the need for a while loop. But if you don't have some sort of character to determine when the loop should stop, you may have trouble :). That is where the EOF character comes in. The EOF character in BeOS is ctrl-d. When the user is done with the program, they can type in ctrl-c to end the loop, which will end this program. Now that we have summarized where we were at, let us continue with the if / else statements.
if (c == '!' || c == '@')
In pseudocode: if the integer c is equivalent to the exclamation point ( ! ) ASCII character (denoted by the single quotes ( ' ) , _OR_ the integer c is equivalent to the at (@) ASCII character, do the following statement:
if (c == '!')
Oooh, an if statement nested in an if statement nested in a while loop. Cool! Now, what we are doing here is determining which character we have (! or @), since we know we have one of the two, or if it wasn't, we would have skipped this if's following statement. If it is the exclamation point character, we want to do this:
cout.put('X');
The function of cout called put() will display one character to the screen, no endlines or newlines or extra characters, just the character you put inside. Use single quotes inside those parentheses, otherwise it is not an ASCII character, and in that case you would want to use the actual number value (which, by the way, for a capital X is the number 88).
Next, if the character was not an exclamation point (meaning it IS an at (@) character):
else cout.put('x');
put() a lower case x to the screen.
Moving back out to the first if - if the character was not one of those two characters, do this:
else cout.put(char(c));
Which will determine what the ASCII character value of the integer c, and cout.put() that character to the screen. This is done by casting the integer c into a char using this:
char(c)
which is then fed to cout.put() in the else statement. What this does is echo back to the screen exactly what the user typed.
Then we end the while loop, return 0 to the OS shell, and exit the program.
Type this into BeIDE and play with it a bit. Make sure you use the exclamation point or the at character (! and @) so you can see the effects.
I will now quickly mention the second type of loop in C++ - do / while loops. The syntax for this is:
do { [statement] } while (conditional expression) ;
The only real difference with this sort of while loop, is that the conditional expression is at the end of the statement, and therefore the statement will be done at least once (even if the while evaluates false). If the while conditional expression is evaluated true, the program executes the loop statement again. Notice the semi-colon ( ; ) at the end of the while conditional expression. This signals the end of the do / while statement, and when a false conditional expression has been evaluated, the program executes the statement immediately after this semi-colon.
Here is a code fragment that you should use in a full program to demonstrate a do / while loop:
[...] int cnt = 1 ; do { cout << cnt << " " ; } while (++cnt <= 20); cout endl; [...]
As you can see, this will act in the same way as a while loop, and in this instance the plain old while loop would be better. There are certain times, though, where you will find that the best solution is to have the loop of a program execute at least once, no matter if the conditional expression is true or false. This is when you would want to use a do / while loop.
Next, we will study the third type of loop structure, the for loop structure.