Part V
Character Input/Output and String Functions
Device an d Character
Input/Output
Unlike many programming languages, C++ contains no input or output commands. C++ is an extremely portable language; a C++ program that compiles and runs on one computer is able also to compile and run on another type of computer. Most incompatibili- ties between computers reside in their input/ output mechanics. Each different device requires a different method of performing I/ O (Input/ Output).
By putting all I/ O capabilities in common functions supplied with each computer’s compiler, not in C++ statements, the design- ers of C++ ensured that programs were not tied to specific hardware for input and output. A compiler has to be modified for every computer for which it is written. This ensures the compiler works with the specific computer and its devices. The compiler writers write I/ O functions for each machine; when your C++ program writes a character to the screen, it works the same whether you have a color PC screen or a UNIX X/ Windows terminal.
This chapter shows you additional ways to perform input and output of data besides the ci n and cout functions you have seen
throughout the book. By providing character-based I/ O functions, C++ gives you the basic I/ O functions you need to write powerful data entry and printing routines.
This chapter introduces you to
-
Stream input and output
-
Redirecting I/ O
-
Printing to the printer
-
Character I/ O functions
-
Buffered and nonbuffered I/ O
By the time you finish this chapter, you will understand the fundamental built-in I/ O functions available in C++. Performing character input and output, one character at a time, might sound like a slow method of I/ O. You will soon realize that character I/ O actually enables you to create more powerful I/ O functions than ci n and cout .
Stream and Character I/ O
C++ views input and output from all devices as streams of characters.
C++ views all input and output as streams of characters. Whether your program receives input from the keyboard, a disk file, a modem, or a mouse, C++ only views a stream of characters. C++ does not have to know what type of device is supplying the input; the operating system handles the device specifics. The designers of C++ want your programs to operate on characters of data without regard to the physical method taking place.
This stream I/ O means you can use the same functions to receive input from the keyboard as from the modem. You can use the same functions to write to a disk file, printer, or screen. Of course, you have to have some way of routing that stream input or output to the proper device, but each program’s I/ O functions works in a similar manner. Figure 21.1 illustrates this concept.
Figure 21.1. All I/O consists of streams of characters.
Standard Device s
Table 21.1 shows a listing of standard I/ O devices. C++ always assumes input comes from stdin, meaning the standard input device. This is usually the keyboard, although you can reroute this default. C++ assumes all output goes to stdout, or the standard output device. There is nothing magic in the words stdin and stdout; however, many people learn their meanings for the first time in C++.
Table 21.1. Standard Devices in C++.
Description |
C++ Name |
MS-DOS Name |
---|---|---|
Screen |
stdout |
CON: |
Keyboard |
stdin |
CON: |
Printer |
stdprn |
PRN: or LPT1: |
Serial Port |
stdaux |
AUX: or COM1: |
Error Messages |
stderr |
CON: |
Disk Files |
none |
Filename |
Take a moment to study Table 21.1. You might think it is confusing that three devices are named CON:. MS-DOS differenti- ates between the screen device called CON: (which stands for console), and the keyboard device called CON: from the context of the data stream. If you send an output stream (a stream of characters) to CON:, MS-DOS routes it to the screen automatically. If you request input from CON:, MS-DOS retrieves the input from the keyboard. (These defaults hold true as long as you have not redi- rected these devices, as shown below.) MS-DOS sends all error messages to the screen (CON:) as well.
The operating system gives you
Redirecting Devices from MS-DO S
The reason cout goes to the screen is simply because st dout is routed to the screen, by default, on most computers. The reason ci n
control over devices.
inputs from the keyboard is because most computers consider the keyboard to be the standard input device, stdin. After compiling your program, C++ does not send data to the screen or retrieve it from the keyboard. Instead, the program sends output to stdout and receives input from stdin. The operating system routes the data to the appropriate device.
MS-DOS enables you to reroute I/ O from their default loca- tions to other devices through the use of the output redirection symbol,
>, and the input redirection symbol, <. The goal of this book is not to delve deeply in operating-system redirection. To learn more about the handling of I/ O, read a good book on MS-DOS, such as Using MS-DOS 5.
Basically, the output redirection symbol informs the operating system that you want standard output to go to a device other than the default (the screen). The input redirection symbol routes input away from the keyboard to another input device. The following example illustrates how this is done in MS-DOS.
Examples
- Suppose
you write a program that uses only ci n and cout for input and output. Instead of receiving input from the key- board, you want the program to get the input from a file called MYDATA. Because ci n receives input from st di n , you must redirect stdin. After compiling the program in a file called MYPGM.EXE, you can redirect its input away from the keyboard with the following DOS command:
C: >MYPGM < MYDATA
Of course, you can include a full pathname either before the program name or filename. There is a danger in redirecting all output such as this, however. All output, including screen prompts for keyboard input, goes to MYDATA. This is probably not acceptable to you in most cases; you still want
prompts and some messages to go to the screen. In the next section, you learn how to separate I/ O, and send some output to one device such as the screen and the rest to another device, such as a file or printer.
- You
can also route the program’s output to the printer by typing this:
C: >MYPGM > PRN:
Route MYPGM output to the printer.
- If
the program required much input, and that input were stored in a file called ANSWERS, you could override the keyboard default device that ci n uses, as in:
C: >MYPGM < ANSWERS
The program reads from the file called ANSWERS every time ci n
required input.
- You
can combine redirection symbols. If you want input from the ANSWERS disk file, and want to send the output to the printer, do the following:
C: >MYPGM < ANSWERS > PRN:
of st r eam allows your program to write to the printer.
Printing Formatted Output t o the Printe r
It’s easy to send program output to the printer using the
of st r eam function. The format of of st r eam is
of st r eam devi ce ( devi ce_name ) ;
of st r eam uses the fstream.h header file.
The following examples show how you can combine cout and
of st r eam to write to both the screen and printer.
Example
The following program asks the user for his or her first and last name. It then prints the name, last name first, to the printer.
/ / Fil ename: C21FPR1. CPP
/ / Pr i nt s a name on t he pr i nt er . #i ncl ude <f st r eam. h>
voi d mai n()
{
char f i r st[ 20]; char l ast[ 20];
cout << “ What i s your f i r st name? “ ; ci n >> f i r st;
cout << “ What i s your l ast name? “ ; ci n >> l ast;
/ / Send names t o t he pr i nt er . of st r eam pr n(“ PRN”) ;
pr n << “ I n a phone book, your name l ooks li ke t hi s: \ n”
; pr n << l ast << “ , “ << f i r st << “ \
n” ;
r et ur n;
}
Character I/O Function s
Because all I/ O is actually character I/ O, C++ provides many functions you can use that perform character input and output. The cout and ci n functions are called formatted I/O functions because they give you formatting control over your input and output. The cout and ci n functions are not character I/ O functions.
There’s nothing wrong with using cout for formatted output, but ci n has many problems, as you have seen. You will now see how to write your own character input routines to replace ci n , as well as use character output functions to prepare you for the upcoming section in this book on disk files.
get () andput ()
input and output
The get ( ) and put ( ) Function s
The most fundamental character I/ O functions are get () and
put () . The put () function writes a single character to the standard
characters from and to any standard devices.
output device (the screen if you don’t redirect it from your operating system). The get () function inputs a single character from the standard input device (the keyboard by default).
The format for get () is
devi ce . get ( char_var ) ;
The get () device can be any standard input device. If you were receiving character input from the keyboard, you use ci n as the device. If you initialize your modem and want to receive characters from it, use of st r eam to open the modem device and read from the device.
The format of put () is
devi ce . put ( char_val ) ;
The char _val can be a character variable, expression, or con- stant. You output character data with put () . The device can be any standard output device. To write a character to your printer, you open PRN with of st r eam .
Examples
- The
following program asks the user for her or his initials a character at a time. Notice the program uses both cout and put () . The cout is still useful for formatted output such as messages to the user. Writing individual characters is best achieved with put () .
The program has to call two get () functions for each char- acter typed. When you answer a get () prompt by typing a
character followed by an Enter keypress, C++ interprets the input as a stream of two characters. The get () first receives the letter you typed, then it has to receive the \ n (newline, supplied to C++ when you press Enter). There are examples that follow that fix this double get () problem.
/ / Fil ename: C21CH1. CPP
/ / I nt r oduces get () and put () . #i ncl ude <f st r eam. h>
voi d mai n()
{
char i n_char ; / / Hol ds i ncomi ng i ni t i al .
char f i r st , l ast ; / / Hol ds conver t ed f i r st and l ast i ni t i al .
cout << “ What i s your f i r st name i ni t i al ? “ ; ci n. get ( i n_char) ; / / Wai t s f or f i r st i ni t i al . f i r st = i n_char ;
ci n. get ( i n_char) ; / / I gnor es newli ne.
cout << “ What i s your l ast name i ni t i al ? “ ; ci n. get ( i n_char) ; / / Wai t s f or l ast i ni t i al . l ast = i n_char ;
ci n. get ( i n_char) ; / / I gnor es newli ne. cout << “ \
nHer e t hey ar e: \ n” ;
cout. put ( f i r st ) ; cout. put ( l ast ) ;
ret urn;
}
Here is the output from this program:
What i s your f i r st name i ni t i al ? G What i s your l ast name i ni t i al ? P
Her e t hey ar e:
GP
- You can add carriage returns to space the output better. To print
the two initials on two separate lines, use put () to put a newline character to cout , as the following program does:
/ / Fil ename: C21CH2. CPP
/ / I nt r oduces get () and put () and uses put () t o out put newl i ne.
#i ncl ude <f st r eam. h> voi d mai n()
{
char i n_char ; / / Hol ds i ncomi ng i ni t i al .
char f i r st , l ast ; / / Hol ds conver t ed f i r st and l ast
/ / i ni t i al .
cout << “ What i s your f i r st name i ni t i al ? “ ; ci n. get ( i n_char) ; / / Wai t s f or f i r st i ni t i al . f i r st = i n_char ;
ci n. get ( i n_char) ; / / I gnor es newli ne.
cout << “ What i s your l ast name i ni t i al ? “ ; ci n. get ( i n_char) ; / / Wai t s f or l ast i ni t i al . l ast = i n_char ;
ci n. get ( i n_char) ; / / I gnor es newli ne. cout << “ \
nHer e t hey ar e: \ n” ;
cout. put ( f i r st ) ; cout. put ( ‘ \ n’ ) ; cout. put ( l ast ) ;
ret urn;
}
- It might have been clearer to define the newline character as a
constant. At the top of the program, you have:
const char NEWLI NE=’ \ n’
The put () then reads:
cout . put ( NEWLI NE) ;
Some programmers prefer to define their character formatting constants and refer to them by name. It’s up to you to decide whether you want to use this method, or whether you want to continue using the \ n character constant in put () .
The get () function is a buffered input function. As you type characters, the data does not immediately go to your program,
rather, it goes to a buffer. The buffer is a section of memory (and has nothing to do with your PC’s type-ahead buffers) managed by C++. Figure 21.2 shows how this buffered function works. When your program approaches a get () , the program temporarily waits as you type the input. The program doesn’t view the characters, as they’re going to the buffer of memory. There is practically no limit to the size of the buffer; it fills with input until you press Enter. Your Enter keypress signals the computer to release the buffer to your
program.
Figure 21.2. get () input goes to a buffer. The buffer is released when you press Enter.
Most PCs accept either buffered or nonbuffered input. The get ch() function shown later in this chapter is nonbuffered. With get () , all input is buffered. Buffered text affects the timing of your program’s input. Your program receives no characters from a get () until you press Enter. Therefore, if you ask a question such as
Do you want t o see t he r epor t agai n ( Y/ N) ?
and use get () for input, the user can press a Y, but the program does not receive the input until the user also presses Enter. The Y and Enter then are sent, one character at a time, to the program where it processes the input. If you want immediate response to a user’s typing (such as the I NKEY$ in BASIC allows), you have to use get ch() .
When receiving characters, you might have to
Example
C21CH2.CPP must discard the newline character. It did so by assigning the input character—from get ( ) —to an extra variable. Obviously, the get () returns a value (the character typed). In this
discard the newline
keypress.
case, it’s acceptable to ignore the return value by not using the character returned by get () . You know the user has to press Enter (to end the input) so it’s acceptable to discard it with an unused get () function call.
When inputting strings such as names and sentences, ci n only allows one word to be entered at a time. The following string asks the user for his or her full name with these two lines:
cout << “ What ar e your f i r st and l ast names? “ ;
ci n >> names; / / Recei ve name i n char act er arr ay names.
The array names only receives the first name; ci n ignores all data to the right of the first space.
You can build your own input function using get () that doesn’t have a single-word limitation. When you want to receive a string of characters from the user, such as his or her first and last name, you can call the get _i n_st r() function shown in the next program.
The mai n() function defines an array and prompts the user for a name. After the prompt, the program calls the get _i n_st r() func- tion and builds the input array a character at a time using get () . The function keeps looping, using the whil e loop, until the user presses Enter (signaled by the newline character, \ n , to C++) or until the maximum number of characters are typed. You might want to use
this function in your own programs. Be sure to pass it a character array and an integer that holds the maximum array size (you don’t want the input string to be longer than the character array that holds it). When control returns to mai n() (or whatever function called get _i n_st r() ), the array has the user’s full input, including the spaces.
/ / Fil ename: C21I N. CPP
/ / Pr ogr am t hat buil ds an i nput st r i ng arr ay usi ng get () .
#i ncl ude <f st r eam. h>
voi d get _i n_st r( char st r [ ] , i nt l en) ;
const i nt MAX=25; / / Si ze of char act er arr ay t o be t yped. voi d mai n()
{
char i nput _st r [ MAX] ; / / Keyboar d i nput f ill s t hi s. cout << “ What i s your f ull name? “ ;
get _i n_st r( i nput _st r , MAX) ; / / St r i ng f r om keyboar d
cout << “ Aft er r et ur n, your name i s “ << i nput _st r << “ \ n” ; r et ur n;
}
/ / **** **** **** **** **** **** **** **** **** *** **** **** **** **** ***
/ / The f oll owi ng f unct i on r equi r es a st r i ng and t he maxi mum
/ / l engt h of t he st r i ng be passed t o i t . I t accept s i nput
/ / f r om t he keyboar d, and sends keyboar d i nput i n t he st r i ng.
/ / On r et ur n, t he calli ng r out i ne has access t o t he st r i ng.
/ / **** **** **** **** **** **** **** **** **** *** **** **** **** **** ***
voi d get _i n_st r( char st r [ ] , i nt l en)
{
i nt i = 0; / / i ndex
char i nput _char ; / / char act er t yped
ci n. get ( i nput _char) ; / / Get next char act er i n st r i ng. whil e ( i < ( l en - 1) && ( i nput _char ! = ‘ \ n’ ))
{
st r [ i ] = i nput _char ; / / Buil d st r i ng a char act er
i ++; / / at a t i me.
ci n. get ( i nput _char) ; / / Recei ve next char act er i n st r i ng.
}
st r [ i ] = ‘ \ 0’ ; / / Make t he char arr ay a st r i ng. r et ur n;
}
get ch() and put ch() offer nonbuffered input
The get ch( ) and put ch( ) Function s
The functions get ch() and put ch() are slightly different from the previous character I/ O functions. Their format is similar to get () and put () ; they read from the keyboard and write to the screen and cannot be redirected, even from the operating system. The formats of get ch() and put ch() are
i nt _var = get ch() ;
and
put ch( i nt _var ) ;
get ch() and put ch() are not AT&T C++ standard functions, but they are usually available with most C++ compilers. get ch() and put ch() are nonbuffered functions. The put ch() character output function is a mirror-image function to get ch() ; it is a nonbuffered
and output that grab
the user’s characters immediately after the user types them.
output function. Because almost every output device made, except for the screen and modem, are inherently buffered, put ch() effec- tively does the same thing as put () .
Another difference in get ch() from the other character input functions is that get ch() does not echo the input characters on the screen as it receives them. When you type characters in response to get () , you see the characters as you type them (as they are sent to the buffer). If you want to see characters received by get ch() , you must follow get ch() with a put ch() . It is handy to echo the characters on the screen so the user can verify that she or he has typed correctly.
Characters input withget ch() are not echoed to the screen as the user types them.
get ch() and
put ch() use the conio.h header file.
Some programmers want to make the user press Enter after answering a prompt or selecting from a menu. They feel the extra time given with buffered input gives the user more time to decide if she or he wants to give that answer; the user can press Backspace and correct the input before pressing Enter.
Other programmers like to grab the user’s response to a single- character answer, such as a menu response, and act on it immedi- ately. They feel that pressing Enter is an added and unneeded burden for the user so they use get ch() . The choice is yours. You should understand both buffered and nonbuffered input so you can use both.
Example
The following program shows the get ch() and put ch() func- tions. The user is asked to enter five letters. These five letters are added (by way of a f or loop) to the character array named l ett er s . As you run this program, notice that the characters are not echoed to the screen as you type them. Because get ch() is unbuffered, the program actually receives each character, adds it to the array, and loops again, as you type them. (If this were buffered input, the program would not loop through the five iterations until you pressed Enter.)
A second loop prints the five letters using put ch() . A third loop prints the five letters to the printer using put () .
/ / Fil ename: C21GCH1. CPP
/ / Uses get ch() and put ch() f or i nput and out put. #i ncl ude <f st r eam. h>
#i ncl ude <coni o. h>
voi d mai n()
{
i nt ct r ; / / f or l oop count er
char l ett er s[ 5] ; / / Hol ds f i ve i nput char act er s. No
/ / r oom i s needed f or t he null zer o
/ / because t hi s arr ay never will be
/ / t r eat ed as a st r i ng. cout << “ Pl ease t ype f i ve l ett er s. . . \ n” ;
f or ( ct r = 0; ct r < 5; ct r ++)
{
l ett er s[ ct r ] = get ch() ; / / Add i nput t o arr ay.
}
f or ( ct r = 0; ct r < 5; ct r ++) / / Pr i nt t hem t o scr een.
{
put ch( l ett er s[ ct r ] ) ;
}
of st r eam pr n(“ PRN”) ;
f or ( ct r = 0; ct r < 5; ct r ++) / / Pr i nt t hem t o pr i nt er .
{
pr n. put ( l ett er s[ ct r ] ) ;
}
ret urn;
}
When you run this program, do not press Enter after the five letters. The get ch() function does not use the Enter. The loop auto- matically ends after the fifth letter because of the unbuffered input and the f or loop.
Review Question s
The answers to the review questions are found in Appendix B.
-
Why
are there no input or output commands in C++?
-
True or false: If you use the character I/ O functions to send
output to stdout, it always goes to the screen.
-
What
is the difference between get ch() and get () ?
-
What function sends formatted output to devices other than the
screen?
-
What are the MS-DOS redirection symbols?
-
What nonstandard function, most similar to get ch() , echoes the
input character to the screen as the user types it?
-
True
or false: When using get () , the program receives your input as you type it.
-
Which keypress releases the buffered input to the program?
-
True or false: Using devices and functions described in this
chapter, it is possible to write one program that sends some output to the screen, some to the printer, and some to the modem.
Review Exercise s
-
Write a
program that asks the user for five letters and prints them in reverse order to the screen, and then to the printer.
-
Write a miniature typewriter program, using get () and put () . In a
loop, get characters until the user presses Enter while he or she is getting a line of user input. Write the line of user input to the printer. Because get () is buffered, nothing goes to the printer until the user presses Enter at the end of each line of text. (Use the string-building input function shown in C21IN.CPP.)
-
Add a put ch() inside the first loop of C21CH1.CPP (this chapter’s
first get () example program) so the characters are echoed to the screen as the user types them.
-
A
palindrome is a word or phrase spelled the same forwards and backwards. Two example palindromes are
Madam, I ’ m Adam
Gol f ? No si r , pr ef er pr i son f l og!
Write a C++ program that asks the user for a phrase. Build the input, a character at a time, using a character input function such as get () . Once you have the full string (store it in a character array), determine whether the phrase is a palindrome. You have to filter special characters (nonalpha- betic), storing only alphabetic characters to a second charac- ter array. You also must convert the characters to uppercase as you store them. The first palindrome becomes:
MADAMI MADAM
Using one or more f or or whil e loops, you can now test the phrase to determine whether it is a palindrome. Print the result of the test on the printer. Sample output should look like:
“ Madam, I ’ m Adam” i s a pali ndr ome.
Summary
You now should understand the generic methods C++ pro- grams use for input and output. By writing to standard I/ O devices, C++ achieves portability. If you write a program for one computer, it works on another. If C++ were to write directly to specific hardware, programs would not work on every computer.
If you still want to use the formatted I/ O functions, such as cout , you can do so. The of st r eam() function enables you to write format- ted output to any device, including the printer.
The methods of character I/ O might seem primitive, and they are, but they give you the flexibility to build and create your own input functions. One of the most often-used C++ functions, a string- building character I/ O function, was demonstrated in this chapter (the C21IN.CPP program).
The next two chapters (Chapter 22, “Character, String, and Numeric Functions,” and Chapter 23, “Introducing Arrays”) intro- duce many character and string functions, including string I/ O functions. The string I/ O functions build on the principles pre- sented here. You will be surprised at the extensive character and string manipulation functions available in the language as well.
Character , String , and Numeri c Functions
C++ provides many built-in functions in addition to the cout , get ch( ) , and st r cpy() functions you have seen so far. These built-in functions increase your productivity and save you programming time. You don’t have to write as much code because the built-in functions perform many useful tasks for you.
This chapter introduces you to
-
Character conversion functions
-
Character and string testing functions
-
String manipulation functions
-
String I/ O functions
-
Mathematical, trigonometric, and logarithmic functions
-
Random-number processing
Character Function s
This section explores many of the character functions available in AT&T C++. Generally, you pass character arguments to the functions, and the functions return values that you can store or print. By using these functions, you off-load much of your work to C++ and allow it to perform the more tedious manipulations of character and string data.
Character T esting Function s
The character Several functions test for certain characteristics of your charac-
functions return True or False results based on the characters you pass to them.
ter data. You can determine whether your character data is alpha- betic, digital, uppercase, lowercase, and much more. You must pass a character variable or literal argument to the function (by placing the argument in the function parentheses) when you call it. These functions return a True or False result, so you can test their return values inside an i f statement or a whil e loop.
Alphabetic and Digital T estin g
The following functions test for alphabetic conditions:
-
i sal pha( c) : Returns True (nonzero) if c is an uppercase or
lowercase letter. Returns False (zero) if c is not a letter.
-
i sl ower( c) : Returns True (nonzero) if c is a lowercase letter.
Returns False (zero) if c is not a lowercase letter.
- i supper( c) : Returns True (nonzero) if c is an uppercase letter.
Returns False (zero) if c is not an uppercase letter.
Remember that any nonzero value is True in C++, and zero is always False. If you use the return values of these functions in a relational test, the True return value is not always 1 (it can be any nonzero value), but it is always considered True for the test.
The following functions test for digits:
- i sdi gi t ( c) : Returns True (nonzero) if c is a digit 0
through 9.
Returns False (zero) if c is not a digit.
- i sxdi gi t (
c ) : Returns True (nonzero) if c is any of the hexa- decimal digits 0 through 9 or A, B, C, D, E, F, a, b, c, d, e, or f. Returns False (zero) if c is anything else. (See Appendix A, “Memory Addressing, Binary, and Hexadecimal Review,” for more information on the hexadecimal numbering system.)
The following function tests for numeric or alphabetical argu- ments:
i sal num( c) : Returns True (nonzero) if c is a digit 0 through 9 or an alphabetic character (either uppercase or lowercase). Returns False (zero) if c is not a digit or a letter.
Example
The following program asks users for their initials. If a user types anything but alphabetic characters, the program displays an error and asks again.
Identify the program and include the input/output header files. The program asks the user for his or her first initial, so declare the character variable i ni t i al to hold the user’s answer.
-
*Ask the user for her or his first initial, and retrieve the user’s
answer.*
-
*If the answer was not an alphabetic character, tell the user this
and repeat step one.*
Print a thank-you message on-screen.
/ / Fil ename: C22I NI. CPP
/ / Asks f or f i r st i ni t i al and t est s
/ / t o ensur e t hat r esponse i s corr ect. #i ncl ude <i ost r eam. h>
#i ncl ude <ct ype. h> voi d mai n()
{
char i ni t i al ;
cout << “ What i s your f i r st i ni t i al ? “ ; ci n >> i ni t i al ;
whil e ( ! i sal pha( i ni t i al ))
{
cout << “ \ nThat was not a vali d i ni t i al ! \ n” ; cout << “ \ nWhat i s your f i r st i ni t i al ? “ ;
ci n >> i ni t i al ;
}
cout << “ \ nThanks! ” ; r et ur n;
}
This use of the not operator (! ) is quite clear. The program
continues to loop as long as the entered character is not alphabetic.
Special Character-Testin g Functions
A few character functions become useful when you have to read from a disk file, a modem, or another operating system device that you route input from. These functions are not used as much as the character functions you saw in the previous section, but they are useful for testing specific characters for readability.
The character-testing functions do not change characters.
The remaining character-testing functions follow:
-
i scnt r l ( c) : Returns True (nonzero) if c is a *control
character* (any character from the ASCII table numbered 0 through 31). Returns False (zero) if c is not a control character.
-
i sgr aph( c) : Returns True (nonzero) if c is any printable
character (a noncontrol character) except a space. Returns False (zero) if c is a space or anything other than a printable character.
-
i spr i nt ( c) : Returns True (nonzero) if c is a printable charac-
ter (a noncontrol character) from ASCII 32 to ASCII 127, including a space. Returns False (zero) if c is not a printable character.
-
i spunct ( c) : Returns True (nonzero) if c is any punctuation
character (any printable character other than a space, a letter, or a digit). Returns False (zero) if c is not a punctuation character.
-
i sspace( c) : Returns True (nonzero) if c is a space, newline (\ n
), carriage return (\ r ), tab (\t ), or vertical tab (\ v ) charac- ter. Returns False (zero) if c is anything else.
Botht ol ower() andt oupper() return lowercase or uppercase arguments.
Character Conversion Function s
The two remaining character functions are handy. Rather than test characters, these functions change characters to their lower- or uppercase equivalents.
-
t ol ower( c) : Converts c to lowercase. Nothing changes if you pass
t ol ower ( ) a lowercase letter or a nonalphabetic character.
-
t oupper( c) : Converts c to uppercase. Nothing changes if you pass
t oupper ( ) an uppercase letter or a nonalphabetic character.
These functions return their changed character values. These functions are useful for user input. Suppose you are asking users a yes or no question, such as the following:
Do you want t o pr i nt t he checks ( Y/ N) ?
Before t oupper() and t ol ower() were developed, you had to check for both a Y and a y to print the checks. Instead of testing for both conditions, you can convert the character to uppercase, and test for a Y.
Example
Here is a program that prints an appropriate message if the user is a girl or a boy. The program tests for G and B after converting the user’s input to uppercase. No check for lowercase has to be done.
Identify the program and include the input/output header files. The program asks the user a question requiring an alphabetic answer, so declare the character variable ans to hold the user’s response.
Ask whether the user is a girl or a boy, and store the user’s answer in ans . The user must press Enter, so incorporate and then discard the Enter keypress. Change the value of ans to uppercase. If the answer is G, print a message. If the answer is B, print a different message. If the answer is something else, print another message.
/ / Fil ename: C22GB. CPP
/ / Det ermi nes whet her t he user t yped a G or a B. #i ncl ude <i ost r eam. h>
#i ncl ude <coni o. h> #i ncl ude <ct ype. h> voi d mai n()
{
char ans; / / Hol ds user ’ s r esponse. cout << “ Ar e you a gi r l or a boy ( G/ B) ? “ ;
ans=get ch() ; / / Get answer .
get ch() ; / / Di scar d newli ne.
cout <<ans<<“ \ n” ;
ans = t oupper( ans) ; / / Conver t answer t o upper case. swi t ch ( ans)
{ case ( ‘ G’ ) : { cout << “ You l ook pr ett y t oday!\ n” ;
br eak; }
case ( ‘ B’ ) : { cout << “ You l ook handsome t oday!\ n” ;
br eak; }
def aul t : { cout << “ Your answer makes no sense!\ n” ; br eak; }
}
r et ur n;
}
Here is the output from the program:
Ar e you a gi r l or a boy ( G/ B) ? B You l ook handsome t oday!
String Function s
Some of the most powerful built-in C++ functions are the string functions. They perform much of the tedious work for which you have been writing code so far, such as inputting strings from the keyboard and comparing strings.
As with the character functions, there is no need to “reinvent the wheel” by writing code when built-in functions do the same task. Use these functions as much as possible.
Now that you have a good grasp of the foundations of C++, you can master the string functions. They enable you to concentrate on your program’s primary purpose, rather than spend time coding your own string functions.
Useful String Function s
You can use a handful of useful string functions for string testing and conversion. You have already seen (in earlier chapters) the st r cpy() string function, which copies a string of characters to a character array.
The string functions work on string literals or on character arrays that contain strings.
String functions that test or manipulate strings follow:
-
st r cat ( s1 , s2 ) : Concatenates (merges) the s2 string to the
end of the s1 character array. The s1 array must have enough reserved elements to hold both strings.
-
st r cmp( s1 , s2 ) : Compares the s1 string with the s2 string on
an alphabetical, element-by-element basis. If s1 alphabetizes before s2 , st r cmp() returns a negative value. If s1 and s2 are the same strings, st r cmp() returns 0. If s1 alphabetizes after s2 , st r cmp() returns a positive value.
-
st r l en( s1) : Returns the length of s1 . Remember, the length of
a string is the number of characters, not including the null zero. The number of characters defined for the character array has nothing to do with the length of the string.
String I/O Function s
In the previous few chapters, you have used a character input function, ci n. get () , to build input strings. Now you can begin to use the string input and output functions. Although the goal of the
Bothget s() and put s() input and output strings.
string-building functions has been to teach you the specifics of the language, these string I/ O functions are much easier to use than writing a character input function.
The string input and output functions are listed as follows:
-
get s( s ) : Stores input from st di n (usually directed to the
keyboard) to the string named s.
-
put s( s ) :
Outputs the s string to st dout (usually directed to the screen by the operating system).
-
f get s( s, l en , dev ) : Stores input from the standard device
specified by dev (such as st di n or st daux ) in the s string. If more than l en characters are input, f get s() discards them.
-
f put s( s, dev ) : Outputs the s string to the standard device
specified by dev.
These four functions make the input and output of strings easy. They work in pairs. That is, strings input with get s() are usually output with put s() . Strings input with f get s() are usually output with f put s() .
Terminate get s() or f get s() input by pressing Enter. Each of these functions handles string-terminating characters in a slightly different manner, as follows:
get s( ) A newline input becomes a null zero (\ 0 ).
put s( ) A null at the end of the string becomes a newline character (\ n ).
f get s( ) A newline input stays, and a null zero is added after it.
f put s( ) The null zero is dropped, and a newline character is not added.
Therefore, when you enter strings with get s() , C++ places a string-terminating character in the string at the point where you press Enter. This creates the input string. (Without the null zero, the
input would not be a string.) When you output a string, the null zero at the end of the string becomes a newline character. This is preferred because a newline is at the end of a line of output and the cursor begins automatically on the next line.
Because f get s() and f put s() can input and output strings from devices such as disk files and telephone modems, it can be critical that the incoming newline characters are retained for the data’s integrity. When outputting strings to these devices, you do not want C++ inserting extra newline characters.
One final function is worth noting, although it is not a string function. It is the ff l ush() function, which flushes (empties) what- ever standard device is listed in its parentheses. To flush the key- board of all its input, you would code as follows:
f f l ush( st di n) ;
When you are doing string input and output, sometimes an extra newline character appears in the keyboard buffer. A previous answer to get s() or get c() might have an extra newline you forgot to discard. When a program seems to ignore get s() , you might have to insert ff l ush( st di n) before get s() .
Flushing the standard input device causes no harm, and using it can clear the input stream so your next get s() works properly. You can also flush standard output devices with ff l ush() to clear the output stream of any characters you sent to it.
Example
The following program shows you how easy it is to use get s() and put s() . The program requests the name of a book from the user using a single get s() function call, then prints the book title with put s( ) .
Identify the program and include the input/output header files. The program asks the user for the name of a book. Declare the character array book with 30 elements to hold the user’s answer.
Ask the user for the book’s title, and store the user’s response in the book array. Display the string stored in book to an output device, probably your screen. Print a thank-you message.
/ / C22GPS1. CPP
/ / I nput s and out put s st r i ngs. #i ncl ude <i ost r eam. h>
#i ncl ude <st di o. h> #i ncl ude <st r i ng. h>
voi d mai n()
{
char book[ 30];
cout << “ What i s t he book t i t l e? “ ;
get s( book) ; / / Get an i nput st r i ng.
put s( book) ; / / Di spl ay t he st r i ng. cout << “ Thanks f or t he book!\ n” ;
r et ur n;
}
The output of the program follows:
What i s t he book t i t l e? Mar y and Her Lambs Mar y and Her Lambs
Thanks f or t he book!
Converting Strings to Number s
Sometimes you have to convert numbers stored in character strings to a numeric data type. AT&T C++ provides three functions that enable you to do this:
-
at oi ( s ) : Converts s to an integer. The name stands for alpha-
betic to integer.
-
at ol ( s ) : Converts s to a long integer. The name stands for
alphabetic to long integer.
- at of ( s ) : Converts s to a floating-point number. The name stands
for alphabetic to floating-point.
The string must contain a valid number. Here is a string that can be converted to an integer:
“ 1232”
The string must hold a string of digits short enough to fit in the target numeric data type. The following string could not be con- verted to an integer with the at oi () function:
“ - 1232495. 654”
However, it could be converted to a floating-point number with the
at of () function.
C++ cannot perform any mathematical calculation with such strings, even if the strings contain digits that represent numbers. Therefore, you must convert any string to its numeric equivalent before performing arithmetic with it.
These functions become more useful to you after you learn about disk files and pointers.
Numeric Function s
This section presents many of the built-in C++ numeric func- tions. As with the string functions, these functions save you time by converting and calculating numbers instead of your having to write functions that do the same thing. Many of these are trigonometric and advanced mathematical functions. You might use some of these numeric functions only rarely, but they are there if you need them. This section concludes the discussion of C++’s standard built-
in functions. After mastering the concepts in this chapter, you are ready to learn more about arrays and pointers. As you develop more skills in C++, you might find yourself relying on these numeric, string, and character functions when you write more powerful programs.
Useful Mathematical Function s
Several built-in numeric functions return results based on numeric variables and literals passed to them. Even if you write only a few science and engineering programs, some of these functions are useful.
These numeric functions return double-precision values.
Here are the functions listed with their descriptions:
-
ceil ( x ) : The ceil () , or ceiling, function rounds numbers up
to the nearest integer.
-
f abs( x ) : Returns the absolute value of x . The absolute value
of a number is its positive equivalent.
-
f l oor( x) : The f l oor() function rounds numbers down to the
nearest integer.
-
f mod( x , y) : The f mod() function returns the floating-point
remainder of (x/ y) with the same sign as x , and y cannot be zero. Because the modulus operator (%) works only with integers, this function is used to find the remainder of floating-point number divisions.
-
pow( x, y) : Returns x raised to the y power, or xy. If
x is less than or equal to zero, y must be an integer. If x equals zero, y cannot be negative.
-
sqr t ( x ) : Returns the square root of x ; x must be greater
than or equal to zero.
Example
The following program uses the f abs() function to compute the difference between two ages.
/ / Fil ename: C22ABS. CPP
/ / Comput es t he di ff er ence bet ween t wo ages. #i ncl ude <i ost r eam. h>
#i ncl ude <mat h. h> voi d mai n()
{
f l oat age1, age2, di ff;
cout << “ \ nWhat i s t he f i r st chil d’ s age? “ ; ci n >> age1;
cout << “ What i s t he second chil d’ s age? “ ; ci n >> age2;
/ / Cal cul at es t he posi t i ve di ff er ence. di f f = age1 - age2;
di f f = f abs( di ff ) ; / / Det ermi nes t he absol ut e val ue.
cout << “ \ nThey ar e “ << di f f << “ year s apar t. ” ; r et ur n;
}
The output from this program follows. Due to f abs() , the order of the ages doesn’t matter. Without absolute value, this program would produce a negative age difference if the first age was less than the second. Because the ages are relatively small, floating-point variables are used in this example. C++ automatically converts floating-point arguments to double precision when passing them to f abs( ) .
What i s t he f i r st chil d’ s age? 10 What i s t he second chil d’ s age? 12
They ar e 2 year s apar t.
Trigonometric Function s
The following functions are available for trigonometric appli- cations:
-
cos( x) : Returns the cosine of the angle x , expressed in
radians.
-
si n( x) : Returns the sine of the angle x , expressed in radians.
-
t an( x) : Returns the tangent of the angle x , expressed in
radians.
These are probably the least-used functions. This is not to belittle the work of scientific and mathematical programmers who need them, however. Certainly, they are grateful that C++ supplies these functions! Otherwise, programmers would have to write their own functions to perform these three basic trigonometric calcula- tions.
Most C++ compilers supply additional trigonometric func- tions, including hyperbolic equivalents of these three functions.
Logarithmic Function s
Three highly mathematical functions are sometimes used in business and mathematics. They are listed as follows:
-
exp( x) : Returns the base of natural logarithm (e) raised to a
power specified by x (ex); e is the mathematical expression for the approximate value of 2.718282.
-
l og( x) :
Returns the natural logarithm of the argument x, mathematically written as l n( x) . x must be positive.
-
l og10( x) : Returns the base-10 logarithm of argument x,
mathematically written as l og10( x) . x must be positive.
Ther and() function produces random integer numbers.
Random-Number Processin g
Random events happen every day. You wake up and it is sunny or rainy. You have a good day or a bad day. You get a phone call from an old friend or you don’t. Your stock portfolio might go up or down in value.
Random events are especially important in games. Part of the fun in games is your luck with rolling dice or drawing cards, combined with your playing skills.
Simulating random events is an important task for computers. Computers, however, are finite machines; given the same input, they always produce the same output. This fact can create some boring games!
The designers of C++ knew this computer setback and found a way to overcome it. They wrote a random-number generating function called r and() . You can use r and() to compute a dice roll or draw a card, for example.
To call the r and() function and assign the returned random number to test, use the following syntax:
t est = r and() ;
The r and() function returns an integer from 0 to 32,767. Never use an argument in the r and() parentheses.
Every time you call r and() in the same program, you receive a different number. If you run the same program over and over,
however, r and() returns the same set of random numbers. One way to receive a different set of random numbers is to call the sr and() function. The format of sr and() follows:
sr and( seed ) ;
where seed is an integer variable or literal. If you don’t call sr and() , C++ assumes a seed value of 1.
The seed value reseeds, or resets, the random-number genera- tor, so the next random number is based on the new seed value. If you call sr and() with a different seed value at the top of a program, r and() returns a different random number each time you run the program.
Review Question s
The answers to the review questions are in Appendix B.
-
How
do the character testing functions differ from the character conversion functions?
-
What are the two string input functions?
-
What is the difference between f l oor() and ceil () ?
-
What
does the following nested function return?
i sal pha( i sl ower ( ‘ s’ ) ) ;
- If the character array st r 1 contains the string Pet er and the
character array st r 2 contains Par ker , what does st r 2 contain after the following line of code executes?
st r cat ( st r 1, st r 2) ;
- What is the output of the following cout ?
cout << f l oor( 8. 5) << “ “ << ceil ( 8. 5) ;
-
True
or false: The i sxdi gi t () and i sgr aph() functions could return the same value, depending on the character passed to them.
-
Assume you declare a character array with the following statement:
char ar a[ 5];
Now suppose the user types Pr ogr ammi ng in response to the following statement:
f get s( ar a, 5, st di n) ;
Would ar a contain Pr og , Pr ogr , or Pr ogr ammi ng ?
- True or false: The following statements print the same results.
cout << pow( 64. 0, ( 1. 0/ 2. 0)) ; cout << sqr t ( 64. 0) ;
Review Exercise s
-
Write
a program that asks users for their ages. If a user types anything other than two digits, display an error message.
-
Write a program that stores a password in a character array called
pass . Ask users for the password. Use st r cmp() to inform users whether they typed the proper password. Use the string I/ O functions for all the program’s input and output.
-
Write a program that rounds up and rounds down the numbers –10.5,
–5.75, and 2.75.
-
Ask
users for their names. Print every name in reverse case; print the first letter of each name in lowercase and the rest of the name in uppercase.
-
Write a program that asks users for five movie titles. Print the
longest title. Use only the string I/ O and manipulation functions presented in this chapter.
-
Write a program that computes the square root, cube root, and fourth
root of the numbers from 10 to 25, inclusive.
-
Ask
users for the titles of their favorite songs. Discard all the special characters in each title. Print the words in the title, one per line. For example, if they enter My Tr ue Love I s Mi ne, Oh, Mi ne! , you should output the following:
My True Love I s
Mi ne Oh Mi ne
- Ask users for the first names of 10 children. Using st r cmp() on
each name, write a program to print the name that comes first in the alphabet.
Summary
You have learned the character, string, and numeric functions that C++ provides. By including the ctype.h header file, you can test and convert characters that a user types. These functions have many useful purposes, such as converting a user’s response to uppercase. This makes it easier for you to test user input.
The string I/ O functions give you more control over both string and numeric input. You can receive a string of digits from the keyboard and convert them to a number with the at o() functions. The string comparison and concatenation functions enable you to test and change the contents of more than one string.
Functions save you programming time because they take over some of your computing tasks, leaving you free to concentrate on your programs. C++’s numeric functions round and manipulate numbers, produce trigonometric and logarithmic results, and pro- duce random numbers.
Now that you have learned most of C++’s built-in functions, you are ready to improve your ability to work with arrays. Chap- ter 23, “Introducing Arrays,” extends your knowledge of character arrays and shows you how to produce arrays of any data type.