# Chapter 18 - Bits, Characters, Strings and Structures - PowerPoint PPT Presentation

Chapter 18 - Bits, Characters, Strings and Structures

1 / 87
Chapter 18 - Bits, Characters, Strings and Structures

## Chapter 18 - Bits, Characters, Strings and Structures

- - - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - - -
##### Presentation Transcript

1. Chapter 18 - Bits, Characters, Strings and Structures Outline 18.1 Introduction 18.2 Structure Definitions 18.3 Initializing Structures 18.4 Using Structures with Functions 18.5 typedef 18.6 Example: High-Performance Card-Shuffling and Dealing Simulation 18.7 Bitwise Operators 18.8 Bit Fields 18.9 Character-Handling Library 18.10 String-Conversion Functions 18.11 Search Functions of the String-Handling Library 18.12 Memory Functions of the String-Handling Library

2. 18.1 Introduction • Structures, bits, characters, C-style strings • C-like techniques • Useful for C++ programmers working with legacy C code • Structures • Hold variables of different data types • Similar to classes, but all data members public • Examine how to use structures • Make card shuffling simulation

3. 18.2 Structure Definitions • Structure definition struct Card { char *face; char *suit; }; • Keyword struct • Card is structure name • Used to declare variable of structure type • Data/functions declared within braces • Structure members need unique names • Structure cannot contain instance of itself, only a pointer • Definition does not reserve memory • Definition ends with semicolon

4. 18.2 Structure Definitions • Declaration • Declared like other variables: use structure type • Card oneCard, deck[ 52 ], *cPtr; • Can declare variables when define structure struct Card { char *face; char *suit;} oneCard, deck[ 52 ], *cPtr;

5. 18.2 Structure Definitions • Structure operations • Assignment to a structure of same type • Taking address (&) • Accessing members (oneCard.face) • Using sizeof • Structure may not be in consecutive bytes of memory • Byte-alignment (2 or 4 bytes) may cause "holes"

6. 0 1 2 3 Byte 00000000 01100001 01100001 18.2 Structure Definitions • Suppose 2-byte boundary for structure members • Use structure with a char and an int • char in first byte • int on a 2-byte boundary • Value in 1-byte hole undefined • Since hole undefined, structures may not compare equally • Cannot use ==

7. 18.3 Initializing Structures • Initializer lists (like arrays) • Card oneCard = { "Three", "Hearts" }; • Comma-separated values, enclosed in braces • If member unspecified, default of 0 • Initialize with assignment • Assign one structure to another Card threeHearts = oneCard; • Assign members individually Card threeHearts; threeHearts.face = “Three”; threeHearts.suit = “Hearts”;

8. 18.4 Using Structures with Functions • Two ways to pass structures to functions • Pass entire structure • Pass individual members • Both pass call-by-value • To pass structures call-by-reference • Pass address • Pass reference to structure • To pass arrays call-by-value • Create structure with array as member • Pass the structure • Pass-by-reference more efficient

9. 18.5 typedef • Keyword typedef • Makes synonyms (aliases) for previously defined data types • Does not create new type, only an alias • Creates shorter type names • Example • typedef Card *CardPtr; • Defines new type name CardPtr as synonym for type Card * • CardPtr myCardPtr; • Card * myCardPtr;

10. 18.6 Example: High-Performance Card-Shuffling and Dealing Simulation • Pseudocode • Create Card structure • Put cards into array deck • Card deck[ 52 ]; • Shuffle the deck • Swap random cards • Deal the cards • Go through deck, print face and suit

11. 1 // Fig. 18.2: fig18_02.cpp 2 // Card shuffling and dealing program using structures. 3 #include <iostream> 4 5 using std::cout; 6 using std::cin; 7 using std::endl; 8 using std::left; 9 using std::right; 10 11 #include <iomanip> 12 13 using std::setw; 14 15 #include <cstdlib> 16 #include <ctime> 17 18 // Card structure definition 19 struct Card { 20 char *face; 21 char *suit; 22 23 }; // end structure Card 24 25 void fillDeck( Card * const, char *[], char *[] ); 26 void shuffle( Card * const ); 27 void deal( Card * const ); Declare the Card structure. In functions, it is used like any other type. fig18_02.cpp(1 of 4)

12. 28 29 int main() 30 { 31 Card deck[ 52 ]; 32 char *face[] = { "Ace", "Deuce", "Three", "Four", 33 "Five", "Six", "Seven", "Eight", "Nine", "Ten", 34 "Jack", "Queen", "King" }; 35 char *suit[] = { "Hearts", "Diamonds", "Clubs", "Spades" }; 36 37 srand( time( 0 ) ); // randomize 38 39 fillDeck( deck, face, suit ); 40 shuffle( deck ); 41 deal( deck ); 42 43 return0; 44 45 } // end main 46 fig18_02.cpp(2 of 4)

13. 47 // place strings into Card structures 48 void fillDeck( Card * const wDeck, 49 char *wFace[], char *wSuit[] ) 50 { 51 for ( int i = 0; i < 52; i++ ) { 52 wDeck[ i ].face = wFace[ i % 13 ]; 53 wDeck[ i ].suit = wSuit[ i / 13 ]; 54 55 } // end for 56 57 } // end function fillDeck 58 59 // shuffle cards 60 void shuffle( Card * const wDeck ) 61 { 62 for ( int i = 0; i < 52; i++ ) { 63 int j = rand() % 52; 64 Card temp = wDeck[ i ]; 65 wDeck[ i ] = wDeck[ j ]; 66 wDeck[ j ] = temp; 67 68 } // end for 69 70 } // end function shuffle 71 Create every face and suit. Note format for accessing a data member in an array of structs. Pick a random card in deck (0-51) and swap with current card. Notice the use of structure assignment. fig18_02.cpp(3 of 4)

14. 72 // deal cards 73 void deal( Card * const wDeck ) 74 { 75 for ( int i = 0; i < 52; i++ ) 76 cout << right << setw( 5 ) << wDeck[ i ].face << " of " 77 << left << setw( 8 ) << wDeck[ i ].suit 78 << ( ( i + 1 ) % 2 ? '\t' : '\n' ); 79 80 } // end function deal fig18_02.cpp(4 of 4)

16. 18.7 Bitwise Operators • Data represented internally as sequences of bits • Each bit can be 0 or 1 • 8 bits form a byte • char is one byte • Other data types larger (int, long, etc.) • Low-level software requires bit and byte manipulation • Operating systems, networking

17. 18.7 Bitwise Operators • Bit operators • Many are overloaded • & (bitwise AND) • 1 if both bits 1, 0 otherwise • | (bitwise inclusive OR) • 1 if either bit 1, 0 otherwise • ^ (bitwise exclusive OR) • 1 if exactly one bit is 1, 0 otherwise • Alternatively: 1 if the bits are different • ~ (bitwise one's complement) • Flips 0 bits to 1, and vice versa

18. 18.7 Bitwise Operators • Bit operators • << (left shift) • Moves all bits left by specified amount • Fills from right with 0 • 1 << SHIFTAMOUNT • >> (right shift with sign extension) • Moves bits right by specified amount • Fill from left can vary

19. 18.7 Bitwise Operators • Next program • Print values in their binary representation • Example: unsigned integer 3 • 00000000 00000000 00000000 00000011 • (For a machine with 4-byte integers) • Computer stores number in this form • Using masks • Integer value with specific bits set to 1 • Used to hide some bits while selecting others • Use with AND

20. 18.7 Bitwise Operators • Mask example • Suppose we want to see leftmost bit of a number • AND with mask • 10000000 00000000 00000000 00000000 (mask) • 10010101 10110000 10101100 00011000 (number) • If leftmost bit of number 1 • Bitwise AND will be nonzero (true) • Leftmost bit of result will be 1 • All other bits are "masked off" (ANDed with 0) • If leftmost bit of number 0 • Bitwise AND will be 0 (false)

21. 18.7 Bitwise Operators • To print every bit • Print leftmost digit • Shift number left • Repeat • To create mask • Want mask of 1000000 … 0000 • How many bits in unsigned? • sizeof(unsigned) * 8 • Start with mask of 1 • Shift one less time (mask is already on first bit) • 1 << sizeof(unsigned) * 8 - 1 • 10000000 00000000 00000000 00000000

22. 1 // Fig. 18.5: fig18_05.cpp 2 // Printing an unsigned integer in bits. 3 #include <iostream> 4 5 using std::cout; 6 using std::cin; 7 using std::endl; 8 9 #include <iomanip> 10 11 using std::setw; 12 13 void displayBits( unsigned ); // prototype 14 15 int main() 16 { 17 unsigned inputValue; 18 19 cout << "Enter an unsigned integer: "; 20 cin >> inputValue; 21 displayBits( inputValue ); 22 23 return0; 24 25 } // end main 26 fig18_05.cpp(1 of 2)

23. 27 // display bits of an unsigned integer value 28 void displayBits( unsigned value ) 29 { 30 const intSHIFT = 8 * sizeof( unsigned ) - 1; 31 const unsignedMASK = 1 << SHIFT; 32 33 cout << setw( 10 ) << value << " = "; 34 35 for ( unsigned i = 1; i <= SHIFT + 1; i++ ) { 36 cout << ( value & MASK ? '1' : '0' ); 37 value <<= 1; // shift value left by 1 38 39 if ( i % 8 == 0 ) // output a space after 8 bits 40 cout << ' '; 41 42 } // end for 43 44 cout << endl; 45 46 } // end function displayBits SHIFT = 32 - 1 = 31 MASK = 10000000 00000000 00000000 00000000 Bitwise AND value and mask. If it is nonzero (true), then the leftmost digit is a 1. Shift value left by 1 to examine next bit. Note use of <<= (same as value = value << 1). fig18_05.cpp(2 of 2)fig18_05.cppoutput (1 of 1) Enter an unsigned integer: 65000 65000 = 00000000 00000000 11111101 11101000

24. 18.7 Bitwise Operators • Upcoming examples • Demo operators • & (AND) • x & y • | (OR) • x | y • ^ (Exclusive OR) • x ^ y • ~ (Complement) • ~x • << and >>(Left shift and right shift)

25. 1 // Fig. 18.7: fig18_07.cpp 2 // Using the bitwise AND, bitwise inclusive OR, bitwise 3 // exclusive OR and bitwise complement operators. 4 #include <iostream> 5 6 using std::cout; 7 using std::cin; 8 9 #include <iomanip> 10 11 using std::endl; 12 using std::setw; 13 14 void displayBits( unsigned ); // prototype 15 16 int main() 17 { 18 unsigned number1; 19 unsigned number2; 20 unsigned mask; 21 unsigned setBits; 22 fig18_07.cpp(1 of 4)

26. 23 // demonstrate bitwise & 24 number1 = 2179876355; 25 mask = 1; 26 cout << "The result of combining the following\n"; 27 displayBits( number1 ); 28 displayBits( mask ); 29 cout << "using the bitwise AND operator & is\n"; 30 displayBits( number1 & mask ); 31 32 // demonstrate bitwise | 33 number1 = 15; 34 setBits = 241; 35 cout << "\nThe result of combining the following\n"; 36 displayBits( number1 ); 37 displayBits( setBits ); 38 cout << "using the bitwise inclusive OR operator | is\n"; 39 displayBits( number1 | setBits ); 40 41 // demonstrate bitwise exclusive OR 42 number1 = 139; 43 number2 = 199; 44 cout << "\nThe result of combining the following\n"; 45 displayBits( number1 ); 46 displayBits( number2 ); 47 cout << "using the bitwise exclusive OR operator ^ is\n"; 48 displayBits( number1 ^ number2 ); fig18_07.cpp(2 of 4)

27. 49 50 // demonstrate bitwise complement 51 number1 = 21845; 52 cout << "\nThe one's complement of\n"; 53 displayBits( number1 ); 54 cout << "is" << endl; 55 displayBits( ~number1 ); 56 57 return0; 58 59 } // end main 60 61 // display bits of an unsigned integer value 62 void displayBits( unsigned value ) 63 { 64 const intSHIFT = 8 * sizeof( unsigned ) - 1; 65 const unsignedMASK = 1 << SHIFT; 66 67 cout << setw( 10 ) << value << " = "; 68 69 for ( unsigned i = 1; i <= SHIFT + 1; i++ ) { 70 cout << ( value & MASK ? '1' : '0' ); 71 value <<= 1; // shift value left by 1 72 73 if ( i % 8 == 0 ) // output a space after 8 bits 74 cout << ' '; 75 76 } // end for fig18_07.cpp(3 of 4)

28. 77 78 cout << endl; 79 80 } // end function displayBits fig18_07.cpp(4 of 4)fig18_07.cppoutput (1 of 1) The result of combining the following 2179876355 = 10000001 11101110 01000110 00000011 1 = 00000000 00000000 00000000 00000001 using the bitwise AND operator & is 1 = 00000000 00000000 00000000 00000001 The result of combining the following 15 = 00000000 00000000 00000000 00001111 241 = 00000000 00000000 00000000 11110001 using the bitwise inclusive OR operator | is 255 = 00000000 00000000 00000000 11111111 The result of combining the following 139 = 00000000 00000000 00000000 10001011 199 = 00000000 00000000 00000000 11000111 using the bitwise exclusive OR operator ^ is 76 = 00000000 00000000 00000000 01001100 The one's complement of 21845 = 00000000 00000000 01010101 01010101 is 4294945450 = 11111111 11111111 10101010 10101010

29. 1 // Fig. 18.11: fig18_11.cpp 2 // Using the bitwise shift operators. 3 #include <iostream> 4 5 using std::cout; 6 using std::cin; 7 using std::endl; 8 9 #include <iomanip> 10 11 using std::setw; 12 13 void displayBits( unsigned ); // prototype 14 15 int main() 16 { 17 unsigned number1 = 960; 18 19 // demonstrate bitwise left shift 20 cout << "The result of left shifting\n"; 21 displayBits( number1 ); 22 cout << "8 bit positions using the left " 23 << "shift operator is\n"; 24 displayBits( number1 << 8 ); 25 fig18_07.cpp(1 of 3)

30. 26 // demonstrate bitwise right shift 27 cout << "\nThe result of right shifting\n"; 28 displayBits( number1 ); 29 cout << "8 bit positions using the right " 30 << "shift operator is\n"; 31 displayBits( number1 >> 8 ); 32 33 return0; 34 35 } // end main 36 37 // display bits of an unsigned integer value 38 void displayBits( unsigned value ) 39 { 40 const intSHIFT = 8 * sizeof( unsigned ) - 1; 41 const unsignedMASK = 1 << SHIFT; 42 43 cout << setw( 10 ) << value << " = "; 44 45 for ( unsigned i = 1; i <= SHIFT + 1; i++ ) { 46 cout << ( value & MASK ? '1' : '0' ); 47 value <<= 1; // shift value left by 1 48 49 if ( i % 8 == 0 ) // output a space after 8 bits 50 cout << ' '; 51 52 } // end for fig18_07.cpp(2 of 3)

31. 53 54 cout << endl; 55 56 } // end function displayBits fig18_07.cpp(3 of 3)fig18_07.cppoutput (1 of 1) The result of left shifting 960 = 00000000 00000000 00000011 11000000 8 bit positions using the left shift operator is 245760 = 00000000 00000011 11000000 00000000 The result of right shifting 960 = 00000000 00000000 00000011 11000000 8 bit positions using the right shift operator is 3 = 00000000 00000000 00000000 00000011

32. 18.8 Bit Fields • Bit field • Member of structure whose size (in bits) has been specified • Enables better memory utilization • Must be declared int or unsigned • Example Struct BitCard { unsigned face : 4; unsigned suit : 2; unsigned color : 1; }; • Declare with name : width • Bit width must be an integer

33. 18.8 Bit Fields • Accessing bit fields • Access like any other structure member Struct BitCard { unsigned face : 4; unsigned suit : 2; unsigned color : 1; }; • myCard.face = 10; • face has 4 bits, can store values 0 - 15 • suitcan store 0 - 3 • color can store 0 or 1

34. 1 // Fig. 18.14: fig18_14.cpp 2 // Representing cards with bit fields in a struct. 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 8 #include <iomanip> 9 10 using std::setw; 11 12 // BitCard structure definition with bit fields 13 struct BitCard { 14 unsigned face : 4; // 4 bits; 0-15 15 unsigned suit : 2; // 2 bits; 0-3 16 unsigned color : 1; // 1 bit; 0-1 17 18 }; // end struct BitBard 19 20 void fillDeck( BitCard * const ); // prototype 21 void deal( const BitCard * const ); // prototype 22 23 int main() 24 { 25 BitCard deck[ 52 ]; 26 27 fillDeck( deck ); 28 deal( deck ); Declare bit fields inside a structure to store card data. fig18_14.cpp(1 of 3)

35. 29 30 return0; 31 32 } // end main 33 34 // initialize BitCards 35 void fillDeck( BitCard * const wDeck ) 36 { 37 for ( int i = 0; i <= 51; i++ ) { 38 wDeck[ i ].face = i % 13; 39 wDeck[ i ].suit = i / 13; 40 wDeck[ i ].color = i / 26; 41 42 } // end for 43 44 } // end function fillDeck 45 Assign to bit fields as normal, but be careful of each field's range. fig18_14.cpp(2 of 3)

36. 46 // output cards in two column format; cards 0-25 subscripted 47 // with k1 (column 1); cards 26-51 subscripted k2 (column 2) 48 void deal( const BitCard * const wDeck ) 49 { 50 for ( int k1 = 0, k2 = k1 + 26; k1 <= 25; k1++, k2++ ) { 51 cout << "Card:" << setw( 3 ) << wDeck[ k1 ].face 52 << " Suit:" << setw( 2 ) << wDeck[ k1 ].suit 53 << " Color:" << setw( 2 ) << wDeck[ k1 ].color 54 << " " << "Card:" << setw( 3 ) << wDeck[ k2 ].face 55 << " Suit:" << setw( 2 ) << wDeck[ k2 ].suit 56 << " Color:" << setw( 2 ) << wDeck[ k2 ].color 57 << endl; 58 59 } // end for 60 61 } // end function deal fig18_14.cpp(3 of 3)

37. Card: 0 Suit: 0 Color: 0 Card: 0 Suit: 2 Color: 1 Card: 1 Suit: 0 Color: 0 Card: 1 Suit: 2 Color: 1 Card: 2 Suit: 0 Color: 0 Card: 2 Suit: 2 Color: 1 Card: 3 Suit: 0 Color: 0 Card: 3 Suit: 2 Color: 1 Card: 4 Suit: 0 Color: 0 Card: 4 Suit: 2 Color: 1 Card: 5 Suit: 0 Color: 0 Card: 5 Suit: 2 Color: 1 Card: 6 Suit: 0 Color: 0 Card: 6 Suit: 2 Color: 1 Card: 7 Suit: 0 Color: 0 Card: 7 Suit: 2 Color: 1 Card: 8 Suit: 0 Color: 0 Card: 8 Suit: 2 Color: 1 Card: 9 Suit: 0 Color: 0 Card: 9 Suit: 2 Color: 1 Card: 10 Suit: 0 Color: 0 Card: 10 Suit: 2 Color: 1 Card: 11 Suit: 0 Color: 0 Card: 11 Suit: 2 Color: 1 Card: 12 Suit: 0 Color: 0 Card: 12 Suit: 2 Color: 1 Card: 0 Suit: 1 Color: 0 Card: 0 Suit: 3 Color: 1 Card: 1 Suit: 1 Color: 0 Card: 1 Suit: 3 Color: 1 Card: 2 Suit: 1 Color: 0 Card: 2 Suit: 3 Color: 1 Card: 3 Suit: 1 Color: 0 Card: 3 Suit: 3 Color: 1 Card: 4 Suit: 1 Color: 0 Card: 4 Suit: 3 Color: 1 Card: 5 Suit: 1 Color: 0 Card: 5 Suit: 3 Color: 1 Card: 6 Suit: 1 Color: 0 Card: 6 Suit: 3 Color: 1 Card: 7 Suit: 1 Color: 0 Card: 7 Suit: 3 Color: 1 Card: 8 Suit: 1 Color: 0 Card: 8 Suit: 3 Color: 1 Card: 9 Suit: 1 Color: 0 Card: 9 Suit: 3 Color: 1 Card: 10 Suit: 1 Color: 0 Card: 10 Suit: 3 Color: 1 Card: 11 Suit: 1 Color: 0 Card: 11 Suit: 3 Color: 1 Card: 12 Suit: 1 Color: 0 Card: 12 Suit: 3 Color: 1 fig18_14.cppoutput (1 of 1)

38. 18.8 Bit Fields • Other notes • Bit fields are not arrays of bits (cannot use []) • Cannot take address of bit fields • Use unnamed bit fields to pad structure Struct Example { unsigned a : 13; unsigned : 3; unsigned b : 4; }; • Use unnamed, zero-width fields to align to boundary Struct Example { unsigned a : 13; unsigned : 0; unsigned b : 4; }; • Automatically aligns b to next boundary

39. 18.9 Character-Handling Library • Character Handling Library • <cctype> • Functions to perform tests and manipulations on characters • Pass character as argument • Character represented by an int • char does not allow negative values • Characters often manipulated as ints • EOF usually has value -1

40. 18.9 Character-Handling Library • Upcoming example • isalpha( int c ) • (All character functions take int argument) • Returns true if c is a letter (A-Z, a-z) • Returns false otherwise • isdigit • Returns true if digit (0-9) • isalnum • Returns true if letter or digit (A-Z, a-z, 0-9) • isxdigit • Returns true if hexadecimal digit (A-F, a-f, 0-9)

41. 1 // Fig. 18.17: fig18_17.cpp 2 // Using functions isdigit, isalpha, isalnum and isxdigit. 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 8 #include <cctype> // character-handling function prototypes 9 10 int main() 11 { 12 cout << "According to isdigit:\n" 13 << ( isdigit( '8' ) ? "8 is a" : "8 is not a" ) 14 << " digit\n" 15 << ( isdigit( '#' ) ? "# is a" : "# is not a" ) 16 << " digit\n"; 17 18 cout << "\nAccording to isalpha:\n" 19 << ( isalpha( 'A' ) ? "A is a" : "A is not a" ) 20 << " letter\n" 21 << ( isalpha( 'b' ) ? "b is a" : "b is not a" ) 22 << " letter\n" 23 << ( isalpha( '&' ) ? "& is a" : "& is not a" ) 24 << " letter\n" 25 << ( isalpha( '4' ) ? "4 is a" : "4 is not a" ) 26 << " letter\n"; 27 Note use of conditional operator: condition ? value if true : value if false fig18_17.cpp(1 of 2)

42. 28 cout << "\nAccording to isalnum:\n" 29 << ( isalnum( 'A' ) ? "A is a" : "A is not a" ) 30 << " digit or a letter\n" 31 << ( isalnum( '8' ) ? "8 is a" : "8 is not a" ) 32 << " digit or a letter\n" 33 << ( isalnum( '#' ) ? "# is a" : "# is not a" ) 34 << " digit or a letter\n"; 35 36 cout << "\nAccording to isxdigit:\n" 37 << ( isxdigit( 'F' ) ? "F is a" : "F is not a" ) 38 << " hexadecimal digit\n" 39 << ( isxdigit( 'J' ) ? "J is a" : "J is not a" ) 40 << " hexadecimal digit\n" 41 << ( isxdigit( '7' ) ? "7 is a" : "7 is not a" ) 42 << " hexadecimal digit\n" 43 << ( isxdigit( '$' ) ? "$ is a" : "$is not a" ) 44 << " hexadecimal digit\n" 45 << ( isxdigit( 'f' ) ? "f is a" : "f is not a" ) 46 << " hexadecimal digit" << endl; 47 48 return0; 49 50 } // end main fig18_17.cpp(2 of 2) 43. According to isdigit: 8 is a digit # is not a digit According to isalpha: A is a letter b is a letter & is not a letter 4 is not a letter According to isalnum: A is a digit or a letter 8 is a digit or a letter # is not a digit or a letter According to isxdigit: F is a hexadecimal digit J is not a hexadecimal digit 7 is a hexadecimal digit$ is not a hexadecimal digit f is a hexadecimal digit fig18_17.cppoutput (1 of 1)

44. 18.9 Character-Handling Library • Upcoming example • islower • Returns true if lowercase letter (a-z) • isupper • Returns true if uppercase letter (A-Z) • tolower • If passed uppercase letter, returns lowercase letter • A to a • Otherwise, returns original argument • toupper • As above, but turns lowercase letter to uppercase • a to A

45. 1 // Fig. 18.18: fig18_18.cpp 2 // Using functions islower, isupper, tolower and toupper. 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 8 #include <cctype> // character-handling function prototypes 9 10 int main() 11 { 12 cout << "According to islower:\n" 13 << ( islower( 'p' ) ? "p is a" : "p is not a" ) 14 << " lowercase letter\n" 15 << ( islower( 'P' ) ? "P is a" : "P is not a" ) 16 << " lowercase letter\n" 17 << ( islower( '5' ) ? "5 is a" : "5 is not a" ) 18 << " lowercase letter\n" 19 << ( islower( '!' ) ? "! is a" : "! is not a" ) 20 << " lowercase letter\n"; 21 22 cout << "\nAccording to isupper:\n" 23 << ( isupper( 'D' ) ? "D is an" : "D is not an" ) 24 << " uppercase letter\n" 25 << ( isupper( 'd' ) ? "d is an" : "d is not an" ) 26 << " uppercase letter\n" 27 << ( isupper( '8' ) ? "8 is an" : "8 is not an" ) 28 << " uppercase letter\n" fig18_18.cpp(1 of 2)

46. 29 << ( isupper( '$' ) ? "$ is an" : "$is not an" ) 30 << " uppercase letter\n"; 31 32 cout << "\nu converted to uppercase is " 33 << static_cast< char >( toupper( 'u' ) ) 34 << "\n7 converted to uppercase is " 35 << static_cast< char >( toupper( '7' ) ) 36 << "\n$ converted to uppercase is " 37 << static_cast< char >( toupper( '$' ) ) 38 << "\nL converted to lowercase is " 39 << static_cast< char >( tolower( 'L' ) ) << endl; 40 41 return0; 42 43 } // end main fig18_18.cpp(2 of 2) 47. According to islower: p is a lowercase letter P is not a lowercase letter 5 is not a lowercase letter ! is not a lowercase letter According to isupper: D is an uppercase letter d is not an uppercase letter 8 is not an uppercase letter$ is not an uppercase letter u converted to uppercase is U 7 converted to uppercase is 7 $converted to uppercase is$ L converted to lowercase is l fig18_18.cppoutput (1 of 1)

48. 18.9 Character-Handling Library • Upcoming example • isspace • Returns true if space ' ', form feed '\f', newline '\n', carriage return '\r', horizontal tab '\t', vertical tab '\v' • iscntrl • Returns true if control character, such as tabs, form feed, alert ('\a'), backspace('\b'), carriage return, newline • ispunct • Returns true if printing character other than space, digit, or letter • $# ( ) [ ] { } ; : %, etc. 49. 18.9 Character-Handling Library • Upcoming example • isprint • Returns true if character can be displayed (including space) • isgraph • Returns true if character can be displayed, not including space 50. 1 // Fig. 18.19: fig18_19.cpp 2 // Using functions isspace, iscntrl, ispunct, isprint, isgraph. 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 8 #include <cctype> // character-handling function prototypes 9 10 int main() 11 { 12 cout << "According to isspace:\nNewline " 13 << ( isspace( '\n' ) ? "is a" : "is not a" ) 14 << " whitespace character\nHorizontal tab " 15 << ( isspace( '\t' ) ? "is a" : "is not a" ) 16 << " whitespace character\n" 17 << ( isspace( '%' ) ? "% is a" : "% is not a" ) 18 << " whitespace character\n"; 19 20 cout << "\nAccording to iscntrl:\nNewline " 21 << ( iscntrl( '\n' ) ? "is a" : "is not a" ) 22 << " control character\n" 23 << ( iscntrl( '$' ) ? "$is a" : "$ is not a" ) 24 << " control character\n"; 25 fig18_19.cpp(1 of 2)