870 likes | 1.02k Views
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
E N D
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
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
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
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;
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"
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 ==
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”;
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
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;
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
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)
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)
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)
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)
King of Clubs Ten of Diamonds Five of Diamonds Jack of Clubs Seven of Spades Five of Clubs Three of Spades King of Hearts Ten of Clubs Eight of Spades Eight of Hearts Six of Hearts Nine of Diamonds Nine of Clubs Three of Diamonds Queen of Hearts Six of Clubs Seven of Hearts Seven of Diamonds Jack of Diamonds Jack of Spades King of Diamonds Deuce of Diamonds Four of Clubs Three of Clubs Five of Hearts Eight of Clubs Ace of Hearts Deuce of Spades Ace of Clubs Ten of Spades Eight of Diamonds Ten of Hearts Six of Spades Queen of Diamonds Nine of Hearts Seven of Clubs Queen of Clubs Deuce of Clubs Queen of Spades Three of Hearts Five of Spades Deuce of Hearts Jack of Hearts Four of Hearts Ace of Diamonds Nine of Spades Four of Diamonds Ace of Spades Six of Diamonds Four of Spades King of Spades fig18_02.cppoutput (1 of 1)
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
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.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
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
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)
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
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)
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
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)
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)
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)
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)
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
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)
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)
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
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
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
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)
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)
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)
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)
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
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
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)
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)
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)
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)
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
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)
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)
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)
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.
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
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)