Tải bản đầy đủ (.pdf) (10 trang)

Absolute C++ (4th Edition) part 37 pdf

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (220.32 KB, 10 trang )

Character Manipulation Tools 365
The value of c1 is set to ’A’, the value of c2 is set to ’B’, and the value of c3 is set to
’\n’. The variable c3 is not set equal to ’C’.
One thing you can do with the member function
get is to have your program detect
the end of a line. The following loop will read a line of input and stop after passing the
newline character
’\n’. Any subsequent input will be read from the beginning of the
next line. For this first example, we have simply echoed the input, but the same tech-
nique would allow you to do whatever you want with the input.
cout << "Enter a line of input and I will echo it:\n";
char symbol;
do
{
cin.get(symbol);
cout << symbol;
} while (symbol != ’\n’);
cout << "That’s all for this demonstration.\n";
This loop will read any line of input and echo it exactly, including blanks. The follow-
ing is a sample dialogue produced by this code:
Enter a line of input and I will echo it:
Do Be Do 1 2 34
Do Be Do 1 2 34
That’s all for this demonstration.
Notice that the newline character ’\n’ is both read and output. Since ’\n’ is output,
the string that begins with the word
"That’s" is on a new line.
The member function
put is analogous to the member function get except that it is
used for output rather than input. The function
put allows your program to output one


character. The member function
cout.put takes one argument, which should be an
expression of type
char, such as a constant or a variable of type char. The value of the
argument is output to the screen when the function is called. For example, the follow-
ing will output the letter
’a’ to the screen:
cout.put(’a’);
'\n'
AND
"\n"
’\n’ and "\n" sometimes seem like the same thing. In a cout statement, they produce the same
effect, but they cannot be used interchangeably in all situations.
’\n’ is a value of type char
and can be stored in a variable of type
char. On the other hand, "\n" is a string that happens to
be made up of exactly one character. Thus,
"\n" is not of type char and cannot be stored in a
variable of type
char.
detecting
the end
of an input
line
put
09_CH09.fm Page 365 Wednesday, August 13, 2003 1:04 PM
366 Strings
Example
The function cout.put does not allow you to do anything you could not do with the
insertion operator

<<, but we include it for completeness. (When we discuss file I/O in
Chapter 12, we will see that
put can be used with an output stream connected to a text
file and is not restricted to being used only with
cout.)
If your program uses
cin.get or cout.put, then just as with other uses of cin and
cout, your program should include one of the following (or something similar):
#include <iostream>
using namespace std;
or
#include <iostream>
using std::cin;
using std::cout;
C
HECKING
I
NPUT
U
SING

A
N
EWLINE
F
UNCTION
The function getInt in Display 9.2 asks the user if the input is correct and asks for a new value if
the user says the input is incorrect. The program in Display 9.2 is just a driver program to test the
function
getInt, but the function, or one very similar to it, can be used in just about any kind of

program that takes its input from the keyboard.
Notice the call to the function newLine( ). The function newLine reads all the characters on the
remainder of the current line but does nothing with them. This amounts to discarding the remain-
der of the line. Thus, if the user types in
No, then the program reads the first letter, which is N, and
T
HE
M
EMBER
F
UNCTION

get
The function get can be used to read one character of input. Unlike the extraction operator, >>,
get reads the next input character, no matter what that character is. In particular, get will read a
blank or the newline character,
’\n’, if either of these are the next input character. The function
get takes one argument, which should be a variable of type char. When get is called, the next
input character is read and the argument variable has its value set equal to this input character.
E
XAMPLE
char nextSymbol;
cin.get(nextSymbol);
As we will see in Chapter 12, if you wish to use get to read from a file, you use an input-file stream
in place of the stream
cin.
newLine( )
09_CH09.fm Page 366 Wednesday, August 13, 2003 1:04 PM
Character Manipulation Tools 367
then calls the function newLine, which discards the rest of the input line. This means that if the

user types
75 on the next input line, as shown in the sample dialogue, the program will read the
number
75 and will not attempt to read the letter o in the word No. If the program did not include
a call to the function
newLine, then the next item read would be the o in the line containing No
instead of the number
75 on the following line.
Display 9.2 Checking Input
(part 1 of 2)
1 //Program to demonstrate the functions newLine and getInput
2 #include <iostream>
3 using namespace std;
4 void newLine( );
5 //Discards all the input remaining on the current input line.
6 //Also discards the ’\n’ at the end of the line.
7 void getInt(int& number);
8 //Sets the variable number to a
9 //value that the user approves of.
10 int main( )
11 {
12 int n;
13 getInt(n);
14 cout << "Final value read in = " << n << endl
15 << "End of demonstration.\n";
16 return 0;
17 }
18 //Uses iostream:
19 void newLine( )
20 {

21 char symbol;
22 do
23 {
24 cin.get(symbol);
25 } while (symbol != ’\n’);
26 }
27 //Uses iostream:
28 void getInt(int& number)
29 {
09_CH09.fm Page 367 Wednesday, August 13, 2003 1:04 PM
368 Strings
Pitfall
U
NEXPECTED

’\n’

IN
I
NPUT
When using the member function get you must account for every character of input, even the
characters you do not think of as being symbols, such as blanks and the newline character,
’\n’.
A common problem when using
get is forgetting to dispose of the ’\n’ that ends every input
line. If there is a newline character in the input stream that is not read (and usually discarded),
then when your program next expects to read a “real” symbol using the member function
get, it
will instead read the character
’\n’. To clear the input stream of any leftover ’\n’, you can use

the function
newLine, which we defined in Display 9.2 (or you can use the function ignore,
which we discuss in the next subsection). Let’s look at a concrete example.
It is legal to mix the different forms of cin. For example, the following is legal:
cout << "Enter a number:\n";
int number;
cin >> number;
cout << "Now enter a letter:\n";
char symbol;
cin.get(symbol);
Display 9.2 Checking Input
(part 2 of 2)
30 char ans;
31 do
32 {
33 cout << "Enter input number: ";
34 cin >> number;
35 cout << "You entered " << number
36 << " Is that correct? (yes/no): ";
37 cin >> ans;
38 newLine( );
39 } while ((ans == ’N’) || (ans == ’n’));
40 }
S
AMPLE
D
IALOGUE
Enter input number: 57
You entered 57 Is that correct? (yes/no): No No No!
Enter input number: 75

You entered 75 Is that correct? (yes/no): yes
Final value read in = 75
End of demonstration.
09_CH09.fm Page 368 Wednesday, August 13, 2003 1:04 PM
Character Manipulation Tools 369
However, this can produce problems, as illustrated by the following dialogue:
Enter a number:
21
Now enter a letter:
A
With this dialogue, the value of number will be 21 as you expect. However, if you expect the value
of the variable
symbol to be ’A’, you will be disappointed. The value given to symbol is ’\n’.
After reading the number
21, the next character in the input stream is the newline character,
’\n’, and so that is read next. Remember, get does not skip over line breaks and spaces. (In
fact, depending on what is in the rest of the program, you may not even get a chance to type in
the
A. Once the variable symbol is filled with the character ’\n’, the program proceeds to what-
ever statement is next in the program. If the next statement sends output to the screen, the screen
will be filled with output before you get a chance to type in the
A.)
The following rewriting of the above code will cause the above dialogue to fill the variable
num-
ber
with 21 and fill the variable symbol with ’A’:
cout << "Enter a number:\n";
int number;
cin >> number;
cout << "Now enter a letter:\n";

char symbol;
cin >> symbol;
Alternatively, you can use the function newLine, defined in Display 9.2, as follows:
cout << "Enter a number:\n";
int number;
cin >> number;
newLine( );
cout << "Now enter a letter:\n";
char symbol;
cin.get(symbol);
As this second rewrite indicates, you can mix the two forms of cin and have your program work
correctly, but it does require some extra care.
As a third alternative, you could use the function ignore, which we discuss in the next subsection.

THE
putback
,
peek
, AND
ignore
MEMBER FUNCTIONS
Sometimes your program needs to know the next character in the input stream. How-
ever, after reading the next character, it might turn out that you do not want to process
09_CH09.fm Page 369 Wednesday, August 13, 2003 1:04 PM
370 Strings
Self-Test Exercises
that character and so would like to “put it back.” For example, if you want your pro-
gram to read up to but not include the first blank it encounters, then your program
must read that first blank in order to know when to stop reading—but then that blank
is no longer in the input stream. Some other part of your program might need to read

and process this blank. One way to deal with this situation is to use the member func-
tion
cin.putback. The function cin.putback takes one argument of type char and
places the value of that argument back in the input stream so that it will be the next
character to be read. The argument can be any expression that evaluates to a value of
type
char. The character that is put back into the input stream with the member func-
tion
putback need not be the last character read; it can be any character you wish.
The
peek member function does what you might expect from its name. cin.peek( )
returns the next character to be read by cin, but it does not use up that character; the
next read starts with that character. In other words, the
peek function peeks ahead to
tell your program what the next character to be read will be.
If you want to skip over input up to some designated character, such as the newline
character
’\n’, you can use the ignore member function. For example, the following
will skip over all input characters up to and including the newline character,
’\n’:
cin.ignore(1000, '\n');
The 1000 is the maximum number of characters to ignore. If the delimiter, in this case
’\n’, has not been found after 1000 characters, then no more characters are ignored.
Of course, a different
int argument can be used in place of 1000 and a different charac-
ter argument can be used in place of
’\n’.
As we will see in Chapter 12, the member functions
putback, peek, and ignore can
be used with

cin replaced by a file input stream object for text file input.
15. Consider the following code (and assume that it is embedded in a complete and correct
program and then run):
char c1, c2, c3, c4;
cout << "Enter a line of input:\n";
cin.get(c1);
cin.get(c2);
cin.get(c3);
cin.get(c4);
cout << c1 << c2 << c3 << c4 << "END OF OUTPUT";
If the dialogue begins as follows, what will be the next line of output?
Enter a line of input:
a b c d e f g
putback
peek
ignore
09_CH09.fm Page 370 Wednesday, August 13, 2003 1:04 PM
Character Manipulation Tools 371
16. Consider the following code (and assume that it is embedded in a complete and correct
program and then run):
char next;
int count = 0;
cout << "Enter a line of input:\n";
cin.get(next);
while (next != ’\n’)
{
if ((count%2) == 0)
cout << next;
count++;
cin.get(next);

}
If the dialogue begins as follows, what will be the next line of output?
Enter a line of input:
abcdef gh
17. Suppose that the program described in Self-Test Exercise 16 is run and the dialogue begins
as follows (instead of beginning as shown in Self-Test Exercise 16). What will be the next
line of output?
Enter a line of input:
0 1 2 3 4 5 6 7 8 9 10 11
18. Consider the following code (and assume that it is embedded in a complete and correct
program and then run):
char next;
int count = 0;
cout << "Enter a line of input:\n";
cin >> next;
while (next != ’\n’)
{
if ((count%2) == 0)
cout << next;
count++;
cin >> next;
}
If the dialogue begins as follows, what will be the next line of output?
Enter a line of input:
0 1 2 3 4 5 6 7 8 9 10 11
True if count is even
09_CH09.fm Page 371 Wednesday, August 13, 2003 1:04 PM
372 Strings

CHARACTER-MANIPULATING FUNCTIONS

In text processing you often want to convert lowercase letters to uppercase or vice versa.
The predefined function
toupper can be used to convert a lowercase letter to an upper-
case letter. For example,
toupper(’a’) returns ’A’. If the argument to the function
toupper is anything other than a lowercase letter, toupper simply returns the argument
unchanged. So
toupper(’A’) returns ’A’, and toupper(’?’) returns ’?’. The function
tolower is similar except that it converts an uppercase letter to its lowercase version.
The functions
toupper and tolower are in the library with the header file <cctype>,
so any program that uses these functions, or any other functions in this library, must
contain the following:
#include <cctype>
Note that <cctype> places all these definitions in the global namespace, and so no
using directive is required. Display 9.3 contains descriptions of some of the most com-
monly used functions in the library
<cctype>.
Display 9.3 Some Functions in <cctype>
(part 1 of 2)

FUNCTION DESCRIPTION EXAMPLE
toupper(
Char_Exp
) Returns the uppercase ver-
sion of
Char_Exp
(as a
value of type
int).

char c = toupper(’a’);
cout << c;
OO
OO
uu
uu
tt
tt
pp
pp
uu
uu
tt
tt
ss
ss
::
::
A
tolower(
Char_Exp
) Returns the lowercase ver-
sion of
Char_Exp
(as a
value of type
int).
char c = tolower(’A’);
cout << c;
OO

OO
uu
uu
tt
tt
pp
pp
uu
uu
tt
tt
ss
ss
::
::
a
isupper(
Char_Exp
) Returns true provided
Char_Exp
is an uppercase
letter; otherwise, returns
false.
if (isupper(c))
cout << "Is uppercase.";
else
cout << "Is not uppercase.";
islower(
Char_Exp
) Returns true provided

Char_Exp
is a lowercase let-
ter; otherwise, returns
false.
char c = ’a’;
if (islower(c))
cout << c << " is lowercase.";
OO
OO
uu
uu
tt
tt
pp
pp
uu
uu
tt
tt
ss
ss
::
::
a is lowercase.
isalpha(
Char_Exp
) Returns true provided
Char_Exp
is a letter of the
alphabet; otherwise,

returns
false.
char c = ’$’;
if (isalpha(c))
cout << "Is a letter.";
else
cout << "Is not a letter.";
OO
OO
uu
uu
tt
tt
pp
pp
uu
uu
tt
tt
ss
ss
::
::
Is not a letter.
09_CH09.fm Page 372 Wednesday, August 13, 2003 1:04 PM
Character Manipulation Tools 373
Display 9.3 Some Functions in <cctype>
(part 2 of 2)

The function isspace returns true if its argument is a whitespace character.

Whitespace characters are all the characters that are displayed as blank space on the
screen, including the blank character, the tab character, and the newline character,
’\n’. If the argument to isspace is not a whitespace character, then isspace returns
false. Thus, isspace(’ ’) returns true and isspace(’a’) returns false.
FUNCTION DESCRIPTION EXAMPLE
isdigit(
Char_Exp
) Returns true provided
Char_Exp
is one of the dig-
its
’0’ through ’9’; oth-
erwise, returns
false.
if (isdigit(’3’))
cout << "It’s a digit.";
else
cout << "It’s not a digit.";
OO
OO
uu
uu
tt
tt
pp
pp
uu
uu
tt
tt

ss
ss
::
::
It’s a digit.
isalnum(
Char_Exp
) Returns true provided
Char_Exp
is either a letter
or a digit; otherwise,
returns
false.
if (isalnum(’3’) && isalnum(’a’))
cout << "Both alphanumeric.";
else
cout << "One or more are not.";
OO
OO
uu
uu
tt
tt
pp
pp
uu
uu
tt
tt
ss

ss
::
::
Both alphanumeric.
isspace(
Char_Exp
) Returns true provided
Char_Exp
is a whitespace
character, such as the
blank or newline charac-
ter; otherwise, returns
false.
//Skips over one "word" and sets c
//equal to the first whitespace
//character after the "word":
do
{
cin.get(c);
} while (! isspace(c));
ispunct(
Char_Exp
) Returns true provided
Char_Exp
is a printing
character other than
whitespace, a digit, or a
letter; otherwise, returns
false.
if (ispunct(’?’))

cout << "Is punctuation.";
else
cout << "Not punctuation.";
isprint(
Char_Exp
) Returns true provided
Char_Exp
is a printing
character; otherwise,
returns
false.
isgraph(
Char_Exp
) Returns true provided
Char_Exp
is a printing char-
acter other than whitespace;
otherwise, returns
false.
isctrl(
Char_Exp
) Returns true provided
Char_Exp
is a control char-
acter; otherwise, returns
false.
whitespace
09_CH09.fm Page 373 Wednesday, August 13, 2003 1:04 PM
374 Strings
Pitfall

For example, the following will read a sentence terminated with a period and echo
the string with all whitespace characters replaced with the symbol
’-’:
char next;
do
{
cin.get(next);
if (isspace(next))
cout << ’-’;
else
cout << next;
} while (next != ’.’);
For example, if the above code is given the following input:
Ahh do be do.
it will produce the following output:
Ahh do-be-do.
toupper

AND

tolower
R
ETURN

int
V
ALUES
In many ways C++ considers characters to be whole numbers, similar to the numbers of type int.
Each character is assigned a number. When the character is stored in a variable of type
char, it is

this number that is placed in the computer’s memory. In C++ you can use a value of type
char as
a number, for example, by placing it in a variable of type
int. You can also store a number of
type
int in a variable of type char (provided the number is not too large). Thus, the type char
can be used as the type for characters or as a type for small whole numbers. Usually you need not
be concerned with this detail and can simply think of values of type
char as being characters
without worrying about their use as numbers. However, when using some of the functions in
<cctype>, this detail can be important. The functions toupper and tolower actually return
values of type
int rather than values of type char; that is, they return the number correspond-
ing to the character we think of them as returning, rather than the character itself. Thus, the fol-
lowing will not output the letter
’A’ but will instead output the number that is assigned to ’A’:
cout << toupper(’a’);
To get the computer to treat the value returned by toupper or tolower as a value of type char
(as opposed to a value of type
int), you need to indicate that you want a value of type char.
One way to do this is to place the value returned in a variable of type
char. The following will
output the character
’A’, which is usually what we want:
char c = toupper(’a’);
cout << c;
09_CH09.fm Page 374 Wednesday, August 13, 2003 1:04 PM

×