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.