380 likes | 484 Views
C++ Programming I Lecture 14. MIS160 Instructor – Larry Langellier. Lecture 14: Class string and Stream Processing. Outline 19.1 Introduction 19.2 string Assignment and Concatenation 19.3 Comparing strings 19.4 Substrings 19.5 Swapping string s 19.6 string Characteristics
E N D
C++ Programming I Lecture 14 MIS160 Instructor – Larry Langellier
Lecture 14: Classstringand StreamProcessing Outline 19.1 Introduction 19.2 string Assignment and Concatenation 19.3 Comparing strings 19.4 Substrings 19.5 Swapping strings 19.6 string Characteristics 19.7 Finding Characters in a string 19.8 Replacing Characters in a string 19.9 Inserting Characters into a string 19.10 Conversion to C-Style char * Strings
The Standard C++ string Class • Let’s define our own String class based on C-strings • Example – strobj.cpp • Thanks to C++, we don’t have to do this – they supply string • Example – sstrass.cpp • Details • #include <string> • Initialization • Assignment (=) • Concatenation (+) • Assignment and Concatenation (+=) • Member Function – swap( )
Introduction • Initialization • string s1( "Hi"); • string s2( 8, 'x'); • string name = "Jim"; • not truly assignment, calls copy constructor WRONG: string s1 = 'c'; string s2( 'u' ); string s3 = 34; string s4( 8 ); • no automatic conversion between int or char to string
Introduction (cont.) • strings do not always end in '\0' • use the [] operator to access elements • first subscript 0 • string not a pointer. &string1[0] != string1 • String length - s1.size() or s1.length() • Inputting strings string myString; cin >> myString; • delimited by whitespace characters string myString; getline(cin, myString); • overloaded getline function • delimited by newline ('\n') • Example – sstrio.cpp
string Assignment and Concatenation • String assignment • = operator: s2 = s1; • assign(): s2.assign(s1); • copies s1 into s2 • s2.assign(s1, startSubscript, numberOfChars); • copies numberOfChars characters in s1 to s2, starting from startSubscript • s2[0] = 'm'; • sets first character of s2 to 'm'
string Assignment and Concatenation (cont.) • More string operations • s2.at(2); • range checked access • s2 += "hi" • concatenates s2 and "hi" • s2.append("_again"); • concatenates "_again" and s2 • s2.append(s1, startSubscript, numberOfChars); • concatenates numberOfChars characters in s1 with s2, starting from startSubscript
1 // Fig. 19.1: fig19_01.cpp 2 // Demonstrating string assignment and concatenation 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 8 #include <string> 9 10 using std::string; 11 12 int main() 13 { 14 string s1( "cat" ), s2, s3; 15 16 s2 = s1; // assign s1 to s2 with = 17 s3.assign( s1 ); // assign s1 to s3 with assign() 18 cout << "s1: " << s1 << "\ns2: " << s2 << "\ns3: " 19 << s3 << "\n\n"; 20 21 // modify s2 and s3 22 s2[ 0 ] = s3[ 2 ] = 'r'; 23 24 cout << "After modification of s2 and s3:\n" 25 << "s1: " << s1 << "\ns2: " << s2 << "\ns3: "; 26 27 // demonstrating member function at() 28 int len = s3.length(); 29 for ( int x = 0; x < len; ++x ) 30 cout << s3.at( x ); 31 32 // concatenation 1. Initialize strings 2. Modify strings 3. Print strings s1: cat s2: cat s3: cat After modification of s2 and s3: s1: cat s2: rat s3: car
33 string s4( s1 + "apult" ), s5; // declare s4 and s5 34 35 // overloaded += 36 s3 += "pet"; // create "carpet" 37 s1.append( "acomb" ); // create "catacomb" 38 39 // append subscript locations 4 thru the end of s1 to 40 // create the string "comb" (s5 was initially empty) 41 s5.append( s1, 4, s1.size() ); 42 43 cout << "\n\nAfter concatenation:\n" << "s1: " << s1 44 << "\ns2: " << s2 << "\ns3: " << s3 << "\ns4: " << s4 45 << "\ns5: " << s5 << endl; 46 47 return 0; 48 } 3. Print strings Program Output After concatenation: s1: catacomb s2: rat s3: carpet s4: catapult s5: comb s1: cat s2: cat s3: cat After modification of s2 and s3: s1: cat s2: rat s3: car After concatenation: s1: catacomb s2: rat s3: carpet s4: catapult s5: comb
Comparing strings • overloaded ==, !=, <, >, <= and >= operators • for string comparisons • return bool values • result = s1.compare(s2); • lexicographical comparison • if s1 > s2, result > 0 • if s1 < s2, result < 0 • if s1 == s2, result = 0 s1.compare(sub1, sub2, s2, sub3, sub4) compares s1 from subscript sub1 to sub2 with s2 from subscript sub3 to sub4. s1.compare(sub1, number, s2) compares number characters in s1 starting from subscript sub1 with s2.
1 // Fig. 19.2: fig19_02.cpp 2 // Demonstrating string comparison capabilities 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 8 #include <string> 9 10 using std::string; 11 12 int main() 13 { 14 string s1( "Testing the comparison functions." ), 15 s2("Hello" ), s3( "stinger" ), z1( s2 ); 16 17 cout << "s1: " << s1 << "\ns2: " << s2 18 << "\ns3: " << s3 << "\nz1: " << z1 << "\n\n"; 19 20 // comparing s1 and z1 21 if ( s1 == z1 ) 22 cout << "s1 == z1\n"; 23 else { // s1 != z1 24 if ( s1 > z1 ) 25 cout << "s1 > z1\n"; 26 else// s1 < z1 27 cout << "s1 < z1\n"; 28 } 29 30 // comparing s1 and s2 31 int f = s1.compare( s2 ); 32 33 if ( f == 0) 1. Initialize strings 2. Compare strings s1: Testing the comparison functions. s2: Hello s3: stinger z1: Hello s1 > z1
34 cout << "s1.compare( s2 ) == 0\n"; 35 else if ( f > 0 ) 36 cout << "s1.compare( s2 ) > 0\n"; 37 else// f < 0 38 cout << "s1.compare( s2 ) < 0\n"; 39 40 // comparing s1 (elements 2 - 5) and s3 (elements 0 - 5) 41 f = s1.compare( 2, 5, s3, 0, 5 ); 42 43 if ( f == 0 ) 44 cout << "s1.compare( 2, 5, s3, 0, 5 ) == 0\n"; 45 else if ( f > 0 ) 46 cout << "s1.compare( 2, 5, s3, 0, 5 ) > 0\n"; 47 else// f < 0 48 cout << "s1.compare( 2, 5, s3, 0, 5 ) < 0\n"; 49 50 // comparing s2 and z1 51 f = z1.compare( 0, s2.size(), s2 ); 52 53 if ( f == 0 ) 54 cout << "z1.compare( 0, s2.size(), s2 ) == 0" << endl; 55 else if ( f > 0 ) 56 cout << "z1.compare( 0, s2.size(), s2 ) > 0" << endl; 57 else// f < 0 58 cout << "z1.compare( 0, s2.size(), s2 ) < 0" << endl; 59 60 return 0; 61 } s1.compare( s2 ) > 0 2. Compare strings s1.compare( 2, 5, s3, 0, 5 ) == 0 z1.compare( 0, s2.size(), s2 ) == 0
s1: Testing the comparison functions. s2: Hello s3: stinger z1: Hello s1 > z1 s1.compare( s2 ) > 0 s1.compare( 2, 5, s3, 0, 5 ) == 0 z1.compare( 0, s2.size(), s2 ) == 0 Program Output
Substrings • Function substr retrieves a substring from a string. s1.substr( startSubScript, number ); • startSubscript - starting subscript • number - number of characters to extract • returns the substring
Swapping strings • Function swap swaps the contents of two strings. s1.swap(s2); • switches s1 and s2
string Characteristics • s1.size() and s1.length() • current number of characters in string • s1.capacity() • number of elements that can be stored without reallocation • s1.max_size() • maximum possible string size • str.empty() • if no characters, returnstrue • s1.resize(newlength) • resizes string to newlength
1 // Fig. 19.5: fig19_05.cpp 2 // Demonstrating functions related to size and capacity 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 using std::cin; 8 9 #include <string> 10 11 using std::string; 12 13 void printStats( const string & ); 14 15 int main() 16 { 17 string s; 18 19 cout << "Stats before input:\n"; 20 printStats( s ); 21 22 cout << "\n\nEnter a string: "; 23 cin >> s; // delimited by whitespace 24 cout << "The string entered was: " << s; 25 26 cout << "\nStats after input:\n"; 27 printStats( s ); 28 29 s.resize( s.length() + 10 ); 30 cout << "\n\nStats after resizing by (length + 10):\n"; 31 printStats( s ); 32 33 cout << endl; 1. Initialize string 2. Function calls 3. Output Stats before input: capacity: 0 max size: 4294967293 size: 0 length: 0 empty: true Stats after input: capacity: 31 max size: 4294967293 size: 6 length: 6 empty: false Enter a string: tomato soup The string entered was: tomato Stats after resizing by (length + 10): capacity: 31 max size: 4294967293 size: 16 length: 16 empty: false
34 return 0; 35 } 36 37 void printStats( const string &str ) 38 { 39 cout << "capacity: " << str.capacity() 40 << "\nmax size: " << str.max_size() 41 << "\nsize: " << str.size() 42 << "\nlength: " << str.length() 43 << "\nempty: " << ( str.empty() ? "true": "false" ); 44 } 3.1 Function definition Program Output Stats before input: capacity: 0 max size: 4294967293 size: 0 length: 0 empty: true Enter a string: tomato soup The string entered was: tomato Stats after input: capacity: 31 max size: 4294967293 size: 6 length: 6 empty: false Stats after resizing by (length + 10): capacity: 31 max size: 4294967293 size: 16 length: 16 empty: false
Finding Characters in a string • Class string find functions: • if found, subscript of match returned • if not found, value of string::nposis returned • s1.find(string) - searches s1 for string • s1.rfind(string) - like find, but searches s1 for string backwards. • s1.find_first_of(string) - finds first occurrence in s1 of any character in string • s1.find_last_of(string)- as above, but last occurrence. Searches s1 backwards. • s1.find_first_not_of(string)- finds first character in s1 NOT in s2. • s1.find_last_not_of(string) - as above, but last character.Searches s1 backwards.
1 // Fig. 19.6: fig19_06.cpp 2 // Demonstrating the string find functions 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 8 #include <string> 9 10 using std::string; 11 12 int main() 13 { 14 // compiler concatenates all parts into one string literal 15 string s( "The values in any left subtree" 16 "\nare less than the value in the" 17 "\nparent node and the values in" 18 "\nany right subtree are greater" 19 "\nthan the value in the parent node" ); 20 21 // find "subtree" at locations 23 and 102 22 cout << "Original string:\n" << s 23 << "\n\n(find) \"subtree\" was found at: " 24 << s.find( "subtree" ) 25 << "\n(rfind) \"subtree\" was found at: " 26 << s.rfind( "subtree" ); 27 28 // find 'p' in parent at locations 62 and 144 29 cout << "\n(find_first_of) character from \"qpxz\" at: " 30 << s.find_first_of( "qpxz" ) 31 << "\n(find_last_of) character from \"qpxz\" at: " 32 << s.find_last_of( "qpxz" ); 33 Original string: The values in any left subtree are less than the value in the parent node and the values in any right subtree are greater than the value in the parent node 1. Initialize string 2. Function calls 3. Output (find) "subtree" was found at: 23 (rfind) "subtree" was found at: 102 (find_first_of) character from "qpxz" at: 62 (find_last_of) character from "qpxz" at: 144
34 // find 'b' at location 25 35 cout << "\n(find_first_not_of) first character not\n" 36 << " contained in \"heTv lusinodrpayft\": " 37 << s.find_first_not_of( "heTv lusinodrpayft" ); 38 39 // find '\n' at location 121 40 cout << "\n(find_last_not_of) first character not\n" 41 << " contained in \"heTv lusinodrpayft\": " 42 << s.find_last_not_of( "heTv lusinodrpayft" ) << endl; 43 44 return 0; 45 } 3. Output Program Output (find_first_not_of) first character not contained in "heTv lusinodrpayft": 25 (find_last_not_of) first character not contained in "heTv lusinodrpayft": 121 Original string: The values in any left subtree are less than the value in the parent node and the values in any right subtree are greater than the value in the parent node (find) "subtree" was found at: 23 (rfind) "subtree" was found at: 102 (find_first_of) character from "qpxz" at: 62 (find_last_of) character from "qpxz" at: 144 (find_first_not_of) first character not contained in "heTv lusinodrpayft": 25 (find_last_not_of) first character not contained in "heTv lusinodrpayft": 121
Replacing Characters in a string • s1.erase(number); • erases everything after element number to the end • s1.replace(sub1, numberToReplace, replacementString, sub2, numberToUse); • sub1 - subscript in s1 where replacement occurs • numberToReplace - number of characters being replaced ins1, starting from sub1 • replacementString - string containing replacement characters • sub2 - beginning subscript of replacement characters in replacementString • numberToUse - number of replacement characters to use in replacementString, starting with sub2
1 // Fig. 19.7: fig19_07.cpp 2 // Demonstrating functions erase and replace 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; Remove all characters from location 62 (the 63rd element) to the end. 7 8 #include <string> 9 10 using std::string; 11 12 int main() 13 { 14 // compiler concatenates all parts into one string 15 string s( "The values in any left subtree" 16 "\nare less than the value in the" 17 "\nparent node and the values in" 18 "\nany right subtree are greater" 19 "\nthan the value in the parent node" ); 20 21 // remove all characters from location 62 22 // through the end of s 23 s.erase( 62 ); 24 25 // output the new string 26 cout << "Original string after erase:\n" << s 27 << "\n\nAfter first replacement:\n"; 28 29 // replace all spaces with a period 30 int x = s.find( " " ); 31 while ( x < string::npos ) { 32 s.replace( x, 1, "." ); 33 x = s.find( " ", x + 1 ); 1. Initialize string 2. Function calls 3. Output Original string after erase: The values in any left subtree are less than the value in the After first replacement: The.values.in.any.left.subtree are.less.than.the.value.in.the
34 } 35 36 cout << s << "\n\nAfter second replacement:\n"; 37 38 // replace all periods with two semicolons 39 // NOTE: this will overwrite characters 40 x = s.find( "." ); 41 while ( x < string::npos ) { 42 s.replace( x, 2, "xxxxx;;yyy", 5, 2 ); 43 x = s.find( ".", x + 1 ); 44 } 45 46 cout << s << endl; 47 return 0; 48 } 3. Output Program Output After second replacement: The;;alues;;n;;ny;;eft;;ubtree are;;ess;;han;;he;;alue;;n;;he Original string after erase: The values in any left subtree are less than the value in the After first replacement: The.values.in.any.left.subtree are.less.than.the.value.in.the After second replacement: The;;alues;;n;;ny;;eft;;ubtree are;;ess;;han;;he;;alue;;n;;he
Inserting Characters into a string • s1.insert(sub1, string) • inserts string before element sub1 in s1 • s1.insert(sub1, string, sub2, numChars); • selects numChars characters, starting from sub2 in string,and inserts them into s1.
Conversion to C-Style char * Strings • strings can be converted to C-style char * strings • s1.data() - conversion to const char * string, not null terminated • s1.c_str() - conversion to const char * string, null terminated (ends with '\0') • stringscan be converted from C-stylechar * strings • s1.copy( chararray, len, termchar ) • Example – sstrchar.cpp
1 // Fig. 19.9: fig19_09.cpp 2 // Converting to C-style strings. Notice the format for inserting strings. 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 8 #include <string> 9 10 using std::string; 11 12 int main() 13 { 14 string s( "STRINGS" ); 15 const char *ptr1 = 0; 16 int len = s.length(); 17 char *ptr2 = new char[ len + 1 ]; // including null 18 19 // copy characters out of string into allocated memory 20 s.copy( ptr2, len, 0 ); 21 ptr2[ len ] = 0; // add null terminator 22 23 // output 24 cout << "string s is " << s 25 << "\ns converted to a C-Style string is " 26 << s.c_str() << "\nptr1 is "; 27 28 // Assign to pointer ptr1 the const char * returned by 29 // function data(). NOTE: this is a potentially dangerous 30 // assignment. If the string is modified, the pointer 31 // ptr1 can become invalid. 32 ptr1 = s.data(); 33 1. Initialize strings 2. Insert strings 3. Print results. string s is STRINGS s converted to a C-Style string is STRINGS ptr1 is STRINGS
34 for ( int k = 0; k < len; ++k ) 35 cout << *( ptr1 + k ); // use pointer arithmetic 36 37 cout << "\nptr2 is " << ptr2 << endl; 38 delete [] ptr2; 39 return 0; 40 } 3. Print results. Program Output ptr2 is STRINGS string s is STRINGS s converted to a C-Style string is STRINGS ptr1 is STRINGS ptr2 is STRINGS
Hangman – An OO Design Example • Does everyone know how to play Hangman? • Like “Wheel of Fortune”, without Vanna and Pat • Let’s Analyze the problem together • Let’s list everything we know about the rules of the game • Don’t worry about writing a computer program right now • Describe the rules as though you were explaining it to a child who is going to play for the first time
Define the Classes • Now that we’ve got a description of the “problem” and an explanation of the rules, let’s decide what Classes we need… • How should we start? • Hint: Nouns • Let’s list the nouns from our analysis on the board • Can you think of any more we might be missing?
Classes (cont.) • Did you get: • Player • Phrase • Game • More?
Data Members • Now let’s define some properties for our Classes • What information do we need to store for each class to describe it? • Where do we start again? • Hint: Adjectives • Go back to the initial description we generated • Are we missing anything from our initial description? • What about those Classes that don’t have any data members?
Just Do It! • Implement each Class • Add data members for the properties • Think about what data type would be appropriate for each • Implement get and set member functions for some of the properties • Consider whether each get/set member function should be public or private
Member Functions • Let’s wrap this up by deciding what member functions we need for each Class • What actions does each object participate in • i.e. What are the Verbs? • We’ve participated in three phases of software development tonight • Analysis • Define the problem • Design • Describe your solution • Implementation • Program your solution • Testing would be the next phase…
Member Functions (cont.) • Did we come up with: • Player • guessALetter() • Game • pickAPhrase() • Play() • Phrase • makeAGuess() • isPuzzleSolved() • displayThePuzzle() ‘with blanks for letters not found yet • What else might we want to do? • Keep score across several phrases • Display the Gallows and Hangman • Display the letters that haven’t been guessed
Sample Solution • Let’s consider a sample solution to this problem • hangman.cpp • Comments, Observations, Criticisms • This implementation isn’t perfect, would you do anything different?
Congratulations!!! • You are on the verge of completing one of the most intense courses on this campus! • C++ is difficult to learn, but well worth the effort • C++ will survive for a long time because it provides capabilities most languages don’t • Execution speed • Low-level access to the computer • Pointers • Most other programming languages you learn will contain a subset of the concepts you learn in C++
Where to from here? • Complete the C++ track • MIS 261 – C++ Programming II • MIS 264 – Visual C++ • Branch to the Java track (this course was a prereq) • MIS 176 – Java Programming I • MIS 276 – Java Programming II • Add another language – Visual Basic • MIS 130 – Visual Basic I • MIS 233 – Visual Basic II • MIS 288 – Windows Software Development • The more languages you know, the easier it will be to get a job • Other important skills • Web and eCommerce • Systems Analysis and Design • SQL and Databases