CIS-255 Home http://www.c-jump.com/bcc/c255c/c255syllabus.htm
|
#include <string> using std::string; // Variety of construction options: string s1; // empty string s2 = s1; // copy constructor string s3 = "Hello"; // from C-string string s4( "Hello", 4 );// first 4 chars string s5( s3, 2, 5 ); // "llo" string s6( 6, 'a' ); // "aaaaaa" |
Positions are 0-based
string::npos is the "non-existent" position.
string::npos is really -1.
The string counts chars, but no null terminator.
As a count, string::npos means end-of-string.
#include <cassert> #include <string> using std::string; void main() { string s1; // empty string s2; // empty s1 = "Fred"; // From null terminated char* s2 = 'a'; // s2 becomes "a" assert( s2 == "a" ); s1 = s2; // Assign one to another // Additional assignments corresponding // to existing constructors: s1.assign( "Hello", 4 ); assert( s1 == "Hell" ); s1.assign( 6, 'a' ); assert( s1 == "aaaaaa" ); // Copy portion of s1 that begins at the position 2 // and up to 5 characters. However, it takes less // than 5 because the end of s1 is reached sooner: s2.assign( s1, 2, 5 ); assert( s2 == "aaaa" ); }
#include <cassert> #include <string> using std::string; void main() { string s1; // empty string s2; // empty s1 += "Fred"; // From null terminated char* s1 += 'a'; // Becomes "Freda" s2 += s1; // Of course, s2 becomes "Freda" // Additional append functions corresponding // to existing constructors: s1.append( "Hello", 4); assert( s1 == "FredaHell" ); s1.append( 6, 'a' ); assert( s1 == "FredaHellaaaaaa" ); // Append portion of s2 that begins at the position 2 // and up to 5 characters. However, it takes less // than 5 because the end of s2 is reached sooner: s1.append( s2, 2, 5 ); // appends "eda" assert( s1 == "FredaHellaaaaaaeda" ); }
#include <string> using std::string; void main() { string s1 = "Hello"; char ch = s1[4]; // uses const version s1[0] = 'J'; // uses non-const version char ch2 = s1[5]; // Bad error - unchecked access! // For checked access, use corresponding // function named at( pos ): char ch3 = s1.at( 5 ); // Bad error - unchecked access! }
The s1.at(pos) behaves just as s1[pos], except that it also performs a range check, throwing an exception of type out_of_range in case that pos is not an actual position in the string.
It's common to define two operator[]s
Allows use on left hand side, as well as on const objects:
template< typename ElementT > class MyArray { public: ElementT& operator[](unsigned int idx); ElementT operator[](unsigned int idx) const; //... };//class MyArray void copy_element( unsigned int idx, MyArray<int> const& src, MyArray<int>& dest ) { // Uses non-const op[] on left, const op[] on right: dest[ idx ] = src[ idx ]; } void main() { MyArray<int> source; MyArray<int> destination; //... copy_element( 0, source, destination ); }
#include <cassert> #include <string> using std::string; void main() { string s1 = "Hello"; assert( s1.length() == 5 ); assert( s1.size() == 5 ); // same as length assert( s1.empty() == false ); // it isn't, so false }
The char* pointer returned by c_str( ) is const
The pointer can only be relied on until the next non-const member of string is called:
#include <stdio.h> #include <string> using std::string; void main() { string file_name = "myfile.txt"; fopen( file_name, "r" ); // Will not compile: cannot convert // from std::string to const char * fopen( file_name.c_str(), "r" ); // Ok: use null-terminated char* char* backdoor = file_name.c_str(); // Will not compile, illegal const char* ptr_fname = file_name.c_str(); // Ok file_name.append( "blah" ); // Invalidates ptr_fname! }
#include <cassert> #include <string> using std::string; void main() { string s1 = "Hello world"; // Find a substring (from front or back) int pos = s1.find("worl"); // returns 6: assert( pos == 6 ); pos = s1.find("foo"); // returns string::npos assert( pos == string::npos ); pos = s1.find('o'); // returns 4: assert( pos == 4 ); pos = s1.rfind('o'); // returns 7: assert( pos == 7 ); // Find any character (from front or back) pos = s1.find_first_of( "aeiou" ); // returns 1; assert( pos == 1 ); pos = s1.find_first_not_of( "aeiou" ); // returns 0; assert( pos == 0 ); }
|
#include <cassert> #include <string> using std::string; void main() { string s1 = "Hello world"; // Compare "Hello world" with "Fred": int result = s1.compare( "Fred" ); // Returns positive: H > F assert( result > 0 ); // Compare "world" with "zone": result = s1.compare( 6, string::npos, "zone" ); // Returns negative: w < z assert( result < 0 ); }
|
operator+ taking 2 args, returning concatenation: overloaded for 5 combinations of std::string and char*
Comparison operators compare two std::strings or char*
Overloaded combinations:
operator== return lhs.compare( rhs ) == 0; operator!= return lhs.compare( rhs ) != 0; operator< return lhs.compare( rhs ) < 0; operator> return lhs.compare( rhs ) > 0; operator<= return lhs.compare( rhs ) <= 0; operator>= return lhs.compare( rhs ) >= 0;
Try std::string, you'll like it!
Use c_str( ) carefully to interact with older code.
Don't sweat all the details, just allow defaults.
Avoid using [ ] all the time, use find( ), etc. when appropriate.