switch
statementsswitch
statement is a bit of a holdover from the
C language on which C++ is based, but it is something you'll
probably see if you look at a lot of programs. You use a
switch
statement when you want to test a single
variable or expression for several different cases. The hitch is
that the variable pretty much needs to be an int
or a
char
, which limits when switch
can be
used. Switch breaks things up into cases. You write
switch(expr) {... where expr is an expression of type
int
or char
, and then list cases consisiting of possible
values of expr. These cases must be constants, and each
case is followed by a :, then a sequence of statements to
be executed, and finally a break;
. In other words,
each case looks like this:
case constk: stmt1 stmt2 ... stmtr break;You can list as many of these cases as you want. You can also put
default: stmt1 stmt2 ... stmtr break;in as one "case". This is a catch-all that catches every situation in which expr didn't match one of the other cases. Here's an example program using
switch
.
It reads a date in "mm/dd/yyyy" format and returns the date in
"dd monthname, yyyy" format.
cin.get()
and eof
x
with the
statement
cin >> x;
cin
skips over leading whitespace in the input
stream, meaning it skips over newline characters ('\n'
),
tabs ('\t'
), and spaces (' '
). This is
a bit of a problem if you want to do something like count the
number of lines in a file. You can read input a char
at a time without skipping over whitespace using
cin.get()
, and you can read from
ifstream
object fin
a char
at a time without skipping over whitespace using
fin.get()
.
So, suppose you wanted to read in a line of text from the user and print out how many characters were in the line, you'd write this:
#include <iostream> using namespace std; int main() { int count = 0; for(char c = cin.get(); c != '\n'; c = cin.get()) count++; cout << "There were " << count << " characters!" << endl; return 0; } |
Suppose fin
is the name of an ifstream
object that you're reading from (remember to include
fstream
if you want to read and write with files).
You can test whether or not you've come to the end of the file
with the expression fin.eof()
which evaluates to
true if you have tried to read beyond the end of the file, and
false otherwise.
So if you wanted to write a program to count the number of
characters in the file "Input.txt
, you'd do something like this:
#include <iostream> #include <fstream> using namespace std; int main() { // Open file stream ifstream FIS("Input"); // Read char c until the end of file int count = 0; for(char c = FIS.get(); !FIS.eof(); c = FIS.get()) count++; cout << "There were " << count << " characters!" << endl; return 0; } |
cout
(or any
ofstream
object)cout
decides to format things
might not agree with the way we'd like to see them formatted.
For example, if x
is a double
with value
4.0, cout
will write "4". Or, for example, the
number of decimal places cout
shows might not be
suffient. Chapter 20 of your book contains lots of information
about the iostream library, and Section 20.9 in particular tells
you how to change the way output is formatted - it even includes
lots of examples.
Formatting can be affected by "i/o manipulators" (you have to
include the library iomanip
for some of these). If
you want to force
cout to always show a decimal point, you "send" it the
manipulator showpoint
(which does not come from
iomanip
, rather is included in the
iostream
library).
double x = 3.0; cout << x << endl; cout << showpoint; cout << x << endl; | YIELDS |
3 3.000000 |
If you want to set the precision to be displayed in printint a
number of type double
use the setprecision(k)
manipulator, where k is the number of digits
you want shown (which does require the
iomanip
library). For example:
double x = 3.1234567890123456789; cout << x << endl; cout << setprecision(15); cout << x << endl; | YIELDS |
3.123456 3.12345678901235 |
Remember! Include the library iomanip
when
using setprecision
!
main()
earlyreturn 0;
" at the end of your program exits your
program. In fact, inside main
you can stick a
"return 0;
" wherever you want and as often as you
want, and it'll exit the program. For example, maybe you want to
write a program that reads an integer k
from
the user and writes out 1/k
. If the user enters
zero, of course, there's a problem. Now we'll just castigate the
user and exit the program if he does that!
#include <iostream> #include <iomanip> using namespace std; int main() { // Get number from user cout << "Enter a non-zero integer: "; int k; cin >> k; // Deal with bad input if (k == 0) { cout << "You follow directions like a Firstie!" << endl; return 1; } // Write out decimal approximation of 1/k cout << setprecision(20); cout << "1/" << k << " is " << 1/double(k) << endl; return 0; } |
1 + 5 + 3 + 48 + 32 =and prints out the resulting sum. This can be done nicely with a do-while
#include <iostream> using namespace std; int main() { int next, sum = 0; char op; do { cin >> next; sum = sum + next; cin >> op; }while(op != '='); return 0; } |
#include <iostream> using namespace std; int main() { int next, sum = 0; char op; // Must initialize with something other // than '=' just to make sure we enter // the loop the first time. op = 'X'; while(op != '=') { cin >> next; sum = sum + next; cin >> op; } return 0; } |
In case you don't find that compelling, here's another example.
Suppose we want to keep reading in int
s from a list
until we read a negative number.
#include <iostream> using namespace std; int main() { int n; do { cin >> n; }while(n >= 0); return 0; } |
#include <iostream> using namespace std; int main() { int n; cin >> n; // read n the first time while(n >= 0) { cin >> n; } return 0; } |
E1 && E2gets evaluated, E1 is evaluated first. If it's false, the value of the expression is false, without ever evaluating E2. Similarly, when
E1 || E2gets evaluated, E1 is evaluated first. If it's true, the value of the expression is true, without ever evaluating E2. This is called short-circuit evaluation. This can have interesting consequences, and can be quite usefull. For example: suppose I want to read in integers from the user until I read one that evenly divides 472, which I will then print out. My first attempt might be
#include <iostream> using namespace std; int main() { int n; do { cin >> n; }while(472 % n != 0); cout << n << endl; return 0; } |
There's a problem with this program, though. If the user enters
0, the program will crash, because 472 % 0 asks the computer to
divide by zero. Clearly if the user enters zero we need to keep
looping to look for a number that divides 472. So we'd like to
modify our program so that it keeps looping if the
n
entered by the user is zero ... as opposed to
crashing, which is what it does now. The following modification
works:
#include <iostream> using namespace std; int main() { int n; do { cin >> n; }while(n == 0 || 472 % n != 0); cout << n << endl; return 0; } |
Now, the only reason this works is the short-circuiting
evaluation, which makes sure that when n == 0
is
true, we never even try to evaluate 472 % n != 0
.
This also means that ++ and -- in expressions involving booleans
can be extremely tricky, especially when a few implicit
conversions come into play as well. For example, here's a game
of C++ Jeapardy: This program outputs the answer, what's the
question?
#include <iostream> using namespace std; int main() { int k, n = 0; cout << "Enter integer k: "; cin >> k; for(int i = 1; i <= k && (k % i || ++n); i++); cout << "The answer is " << n << endl; return 0; } |