Példa 1
=========

template<class Ch> struct char_traits { };



Példa 2
=========

template<> struct char_traits<char> 
{       // char_traits operations should not throw exceptions
    typedef char char_type;     // type of character

    static void assign(char_type&, const char_type&);       // = for char_type

    // integer representation of characters:

    typedef int int_type;           // type of integer value of character

    static char_type to_char_type(const int_type&);         // int to char conversion
    static int_type to_int_type(const char_type&);          // char to int conversion
    static bool eq_int_type(const int_type&, const int_type&);  // ==

    // char_type comparisons:

    static bool eq(const char_type&, const char_type&);     // ==
    static bool lt(const char_type&, const char_type&);     // <

    // operations on s[n] arrays:

    static char_type* move(char_type* s, const char_type* s2, size_t n);
    static char_type* copy(char_type* s, const char_type* s2, size_t n);
    static char_type* assign(char_type* s, size_t n, char_type a);

    static int compare(const char_type* s, const char_type* s2, size_t n);
    static size_t length(const char_type*);
    static const char_type* find(const char_type* s, int n, const char_type&);

    // I/O related:

    typedef streamoff off_type; // offset in stream
    typedef streampos pos_type; // position in stream
    typedef mbstate_t state_type;   // multi-byte stream state

    static int_type eof();              // end-of-file
    static int_type not_eof(const int_type& i); // i unless i equals eof(); if not any value!=eof()
    static state_type get_state(pos_type p);    // multibyte conversion state of character in p
};



Példa 3
=========

template<> struct char_traits<wchar_t> 
{
    typedef wchar_t char_type;
    typedef wint_t int_type;
    typedef wstreamoff off_type;
    typedef wstreampos pos_type;

    // like char_traits<char>
};



Példa 4
=========

template<class Ch, class Tr = char_traits<Ch>, class A = allocator<Ch> >
class std::basic_string 
{
public:
    // ...
};



Példa 5
=========

typedef basic_string<char> string;
typedef basic_string<wchar_t> wstring;



Példa 6
=========

template<class Ch, class Tr = char_traits<Ch>, class A = allocator<Ch> >
class basic_string 
{
public:
    // types (much like vector, list, etc. ):

    typedef Tr traits_type;     // specific to basic_string

    typedef typename Tr::char_type value_type;
    typedef A allocator_type;
    typedef typename A::size_type size_type;
    typedef typename A::difference_type difference_type;

    typedef typename A::reference reference;
    typedef typename A::const_reference const_reference;
    typedef typename A::pointer pointer;
    typedef typename A::const_pointer const_pointer;

    typedef implementation_defined1 iterator;
    typedef implementation_defined2 const_iterator;

    typedef std::reverse_iterator<iterator> reverse_iterator;
    typedef std::reverse_iterator<const_iterator> const_reverse_iterator;

    // ...
};



Példa 7
=========

typedef basic_string<unsigned char> Ustring;

struct Jchar { /* ... */ };     // Japanese character type
typedef basic_string<Jchar> Jstring;



Példa 8
=========

Ustring first_word(const Ustring& us)
{
    Ustring::size_type pos = us.find(' ');
    return Ustring(us,0,pos);           
}

Jstring first_word(const Jstring& js)
{
    Jstring::size_type pos = js.find(' ');  
    return Jstring(js,0,pos);           
}



Példa 9
=========

template<class S> S first_word(const S& s)
{
    typename S::size_type pos = s.find(' ');
    return S(s,0,pos);                  
}



Példa 10
=========

template<class Ch, class Tr = char_traits<Ch>, class A = allocator<Ch> >
class basic_string 
{
public:
    // ...
    // iterators (like vector, list, etc.):

    iterator begin();
    const_iterator begin() const;
    iterator end();
    const_iterator end() const;

    reverse_iterator rbegin();
    const_reverse_iterator rbegin() const;
    reverse_iterator rend();
    const_reverse_iterator rend() const;

    // ...
};



Példa 11
=========

void f(string& s)
{
    string::iterator p = find(s.begin(),s.end(),'a');
    // ...
}



Példa 12
=========

template<class Ch, class Tr = char_traits<Ch>, class A = allocator<Ch> >
class basic_string {
public:
    // ...
    // element access (like vector):

    const_reference operator[](size_type n) const;  // unchecked access
    reference operator[](size_type n);

    const_reference at(size_type n) const;          // checked access
    reference at(size_type n);

    // ...
};



Példa 13
=========

template<class Ch, class Tr = char_traits<Ch>, class A = allocator<Ch> >
class basic_string 
{
public:
    // ...
    // constructors, etc. (a bit like vector and list) 

    explicit basic_string(const A& a = A());
    basic_string(const basic_string& s,
            size_type pos = 0, size_type n = npos, const A& a = A());
    basic_string(const Ch* p, size_type n, const A& a = A());
    basic_string(const Ch* p, const A& a = A());
    basic_string(size_type n, Ch c, const A& a = A());
    template<class In> basic_string(In first, In last, const A& a = A());

    ~basic_string();

    static const size_type npos;    // ``all characters'' marker

    // ...
};



Példa 14
=========

void f(char* p,vector<char>&v)
{
    string s0;              // the empty string
    string s00 = "";        // also the empty string

    string s1 = 'a';        // error: no conversion from char to string
    string s2 = 7;          // error: no conversion from int to string
    string s3(7);           // error: no constructor taking one int argument
    string s4(7,'a');       // 7 copies of 'a'; that is "aaaaaaa"

    string s5 = "Frodo";    // copy of "Frodo"
    string s6 = s5;         // copy of s5

    string s7(s5,3,2);      // s5[3] and s5[4]; that is "do"
    string s8(p+7,3);       // p[7], p[8], and p[9]
    string s9(p,7,3);       // string(string(p),7,3), possibly expensive

    string s10(v.begin(),v.end());  // copy all characters from v
}



Példa 15
=========

void f(string s)
{
    wstring ws(s.begin(),s.end());  // copy all characters from s
    // ...
}



Példa 16
=========

void f()
{
    string s = "Snobol4";
    string s2(s,100,2); // character position beyond end of string: throw out_of_range()
    string s3(s,2,100); // character count too large: equivalent to s3(s,2,s.size()\-2)
    string s4(s,2,string::npos);    // the characters starting from s[2]
}



Példa 17
=========

void g(string& s)
{
    string s5(s,-2,3);  // large position!: throw out_of_range()
    string s6(s,3,-2);  // large character count!: ok
}



Példa 18
=========

string s(string::npos,'a'); // throw length_error()



Példa 19
=========

template<class Ch, class Tr = char_traits<Ch>, class A = allocator<Ch> >
class basic_string {
public:
    // ...
    // assignment (a bit like vector and list):

    basic_string& operator=(const basic_string& s);
    basic_string& operator=(const Ch* p);
    basic_string& operator=(Ch c);

    basic_string& assign(const basic_string&);
    basic_string& assign(const basic_string& s, size_type pos, size_type n);
    basic_string& assign(const Ch* p, size_type n);
    basic_string& assign(const Ch* p);
    basic_string& assign(size_type n, Ch c);
    template<class In> basic_string& assign(In first, In last);

    // ...
};



Példa 20
=========

void g()
{
    string s1 = "Knold";
    string s2 = "Tot";

    s1 = s2;        // two copies of "Tot"
    s2[1] = 'u';    // s2 is "Tut", s1 is still "Tot"
}



Példa 21
=========

void f()
{
    string s = 'a'; // error: initialization by char
    s = 'a';        // ok: assignment
    s = "a";
    s = s;
}   



Példa 22
=========

template<class Ch, class Tr = char_traits<Ch>, class A = allocator<Ch> >
class basic_string 
{
public:
    // ...
    // conversion to C-style string:

    const Ch* c_str() const;
    const Ch* data() const;
    size_type copy(Ch* p, size_type n, size_type pos = 0) const;

    // ...
};



Példa 23
=========

void f()
{
    string s = "equinox";       // s.length()==7
    const char* p1 = s.data();  // p1 points to seven characters
    printf("p1 = %s\n",p1);     // bad: missing terminator
    p1[2] = 'a';                // error: p1 points to a const array
    s[2] = 'a';
    char c = p1[1];         // bad: access of s.data() after modification of s

    const char* p2 = s.c_str(); // p2 points to eight characters
    printf("p2 = %s\n",p2);     // ok: c_str() adds terminator
}



Példa 24
=========

void f(string s)
{
    int i = atoi(s.c_str());    // get int value of digits in string
    // ...
}



Példa 25
=========

char* c_string(const string& s)
{
    char* p = new char[s.length()+1];   // note: +1
    s.copy(p,string::npos);
    p[s.length()] = 0;              // note: add terminator
    return p;
}



Példa 26
=========

extern "C" int atoi(const char*);

int atoi(const string& s)
{
    return atoi(s.c_str());
}



Példa 27
=========

template<class Ch, class Tr = char_traits<Ch>, class A = allocator<Ch> >
class basic_string {
public:
    // ...

    int compare(const basic_string& s) const;   // combined > and ==
    int compare(const Ch* p) const;

    int compare(size_type pos, size_type n, const basic_string& s) const;
    int compare(size_type pos, size_type n,
            const basic_string& s, size_type pos2, size_type n2) const;
    int compare(size_type pos, size_type n, const Ch* p, size_type n2 = npos) const;

    // ...
};



Példa 28
=========

int cmp_nocase(const string& s, const string& s2)
{
    string::const_iterator p = s.begin();
    string::const_iterator p2 = s2.begin();

    while (p!=s.end() && p2!=s2.end()) {
        if (toupper(*p)!=toupper(*p2)) return (toupper(*p)<toupper(*p2)) ? -1 : 1;
        ++p;
        ++p2;
    }

    return (s2.size()==s.size()) ? 0 : (s.size()<s2.size()) ? -1 : 1;   // size is unsigned
}

void f(const string& s, const string& s2)
{
    if (s == s2) {                  // case sensitive compare of s and s2
        // ...
    }

    if (cmp_nocase(s,s2) == 0) {        // case insensitive compare of s and s2
        // ...
    }

    // ...  
}



Példa 29
=========

template<class Ch, class Tr, class A>
bool operator==(const basic_string<Ch,Tr,A>&, const basic_string<Ch,Tr,A>&);

template<class Ch, class Tr, class A>
bool operator==(const Ch*, const basic_string<Ch,Tr,A>&);

template<class Ch, class Tr, class A>
bool operator==(const basic_string<Ch,Tr,A>&, const Ch*);

// similar declarations for !=, >, <, >=, and <=



Példa 30
=========

void f(const string& name)
{
    if (name =="Obelix" || "Asterix"==name) {   // use optimized ==
        // ...
    }
}



Példa 31
=========

template<class Ch, class Tr = char_traits<Ch>, class A = allocator<Ch> >
class basic_string 
{
public:
    // ...
    // add characters after (*this)[length()-1]:

    basic_string& operator+=(const basic_string& s);
    basic_string& operator+=(const Ch* p);
    basic_string& operator+=(Ch c);
    void push_back(Ch c);

    basic_string& append(const basic_string& s);
    basic_string& append(const basic_string& s, size_type pos, size_type n);
    basic_string& append(const Ch* p, size_type n);
    basic_string& append(const Ch* p);
    basic_string& append(size_type n, Ch c);
    template<class In> basic_string& append(In first, In last);

    // insert characters before (*this)[pos]:

    basic_string& insert(size_type pos, const basic_string& s);
    basic_string& insert(size_type pos, const basic_string& s, size_type pos2, size_type n);
    basic_string& insert(size_type pos, const Ch* p, size_type n);
    basic_string& insert(size_type pos, const Ch* p);
    basic_string& insert(size_type pos, size_type n, Ch c);

    // insert characters before p:

    iterator insert(iterator p, Ch c);
    void insert(iterator p, size_type n, Ch c);
    template<class In> void insert(iterator p, In first, In last);

    // ...
};



Példa 32
=========

string complete_name(const string& first_name, const string& family_name)
{
    string s = first_name;
    s += ' ';
    s += family_name;
    return s;
}



Példa 33
=========

string complete_name2(const string& first_name, const string& family_name)  // poor algorithm
{
    string s = family_name;
    s.insert(s.begin(),' ');
    return s.insert(0,first_name);
..  return s;
}



Példa 34
=========

template<class Ch, class Tr, class A>
basic_string<Ch,Tr,A>
operator+(const basic_string<Ch,Tr,A>&, const basic_string<Ch,Tr,A>&);

template<class Ch, class Tr, class A>
basic_string<Ch,Tr,A> operator+(const Ch*, const basic_string<Ch,Tr,A>&);

template<class Ch, class Tr, class A>
basic_string<Ch,Tr,A> operator+(Ch, const basic_string<Ch,Tr,A>&);

template<class Ch, class Tr, class A>
basic_string<Ch,Tr,A> operator+(const basic_string<Ch,Tr,A>&, const Ch*);

template<class Ch, class Tr, class A>
basic_string<Ch,Tr,A> operator+(const basic_string<Ch,Tr,A>&, Ch);



Példa 35
=========

string complete_name3(const string& first_name, const string& family_name)
{
    return first_name + ' ' + family_name;
}



Példa 36
=========

template<class Ch, class Tr = char_traits<Ch>, class A = allocator<Ch> >
class basic_string {
public:
    // ...
    // find subsequence (like search()):

    size_type find(const basic_string& s, size_type i = 0) const;
    size_type find(const Ch* p, size_type i, size_type n) const;
    size_type find(const Ch* p, size_type i = 0) const;
    size_type find(Ch c, size_type i = 0) const;

    // find subsequence searching backwards from the end (like find_end()):

    size_type rfind(const basic_string& s, size_type i = npos) const;
    size_type rfind(const Ch* p, size_type i, size_type n) const;
    size_type rfind(const Ch* p, size_type i = npos) const;
    size_type rfind(Ch c, size_type i = npos) const;

    // find character (like find_first_of() in _algo.find_):

    size_type find_first_of(const basic_string& s, size_type i = 0) const;
    size_type find_first_of(const Ch* p, size_type i, size_type n) const;
    size_type find_first_of(const Ch* p, size_type i = 0) const;
    size_type find_first_of(Ch c, size_type i = 0) const;

    // find character from argument searching backwards from the end:

    size_type find_last_of(const basic_string& s, size_type i = npos) const;
    size_type find_last_of(const Ch* p, size_type i, size_type n) const;
    size_type find_last_of(const Ch* p, size_type i = npos) const;
    size_type find_last_of(Ch c, size_type i = npos) const;

    // find character not in argument:

    size_type find_first_not_of(const basic_string& s, size_type i = 0) const;
    size_type find_first_not_of(const Ch* p, size_type i, size_type n) const;
    size_type find_first_not_of(const Ch* p, size_type i = 0) const;
    size_type find_first_not_of(Ch c, size_type i = 0) const;

    // find character not in argument searching backwards from the end:

    size_type find_last_not_of(const basic_string& s, size_type i = npos) const;
    size_type find_last_not_of(const Ch* p, size_type i, size_type n) const;
    size_type find_last_not_of(const Ch* p, size_type i = npos) const;
    size_type find_last_not_of(Ch c, size_type i = npos) const;
    // ...
};



Példa 37
=========

void f()
{
    string s = "accdcde";
..  typedef  ST;
..  
    string::size_type i1 = s.find("cd");                // i1 = 2   s[2]=='c' && s[3]=='d'
    string::size_type i2 = s.rfind("cd");               // i2 = 4   s[4]=='c' && s[5]=='d'
    string::size_type i3 = s.find_first_of("cd");       // i3 = 1   s[1] == 'c'
    string::size_type i4 = s.find_last_of("cd");        // i4 = 5   s[5] == 'd'
    string::size_type i5 = s.find_first_not_of("cd");   // i5 = 0   s[0]!='c' && s[0]!='d'
    string::size_type i6 = s.find_last_not_of("cd");    // i6 = 6   s[6]!='c' && s[6]!='d'
}



Példa 38
=========

template<class Ch, class Tr = char_traits<Ch>, class A = allocator<Ch> >
class basic_string {
public:
    // ...
    // replace [ (*this)[i], (*this)[i+n] [ with other characters:

    basic_string& replace(size_type i, size_type n, const basic_string& s);
    basic_string& replace(size_type i, size_type n,
                    const basic_string& s, size_type i2, size_type n2);
    basic_string& replace(size_type i, size_type n, const Ch* p, size_type n2);
    basic_string& replace(size_type i, size_type n, const Ch* p);
    basic_string& replace(size_type i, size_type n, size_type n2, Ch c);

    basic_string& replace(iterator i, iterator i2, const basic_string& s);
    basic_string& replace(iterator i, iterator i2, const Ch* p, size_type n);
    basic_string& replace(iterator i, iterator i2, const Ch* p);
    basic_string& replace(iterator i, iterator i2, size_type n, Ch c);
    template<class In> basic_string& replace(iterator i, iterator i2, In j, In j2);

    // remove characters from string (``replace with nothing''):

    basic_string& erase(size_type i = 0, size_type n = npos);
    iterator erase(iterator i);
    iterator erase(iterator first, iterator last);

    // ...
};



Példa 39
=========

void f()
{
    string s = "but I have heard it works even if you don't believe in it";
    s.erase(0,4);                       // erase initial "but "
    s.replace(s.find("even"),4,"only");
    s.replace(s.find("don't"),5,"");    // erase by replacing with "" 
}



Példa 40
=========

template<class Ch, class Tr = char_traits<Ch>, class A = allocator<Ch> >
class basic_string {
public:
    // ...
    // address substring:

    basic_string substr(size_type i = 0, size_type n = npos) const;
    // ...
};



Példa 41
=========

template<class Ch> class Basic_substring {
public:
    typedef typename basic_string<Ch>::size_type size_type;

    Basic_substring(basic_string<Ch>& s, size_type i, size_type n);     // s[i]..s[i+n\-1]
    Basic_substring(basic_string<Ch>& s, const basic_string<Ch>& s2);   // s2 in s
    Basic_substring(basic_string<Ch>& s, const Ch* p);              // *p in s

    Basic_substring& operator=(const basic_string<Ch>&);        // write through to *ps
    Basic_substring& operator=(const Basic_substring<Ch>&);
    Basic_substring& operator=(const Ch*);
    Basic_substring& operator=(Ch);

    operator basic_string<Ch>() const;                      // read from *ps
    operator const Ch* () const;                            // use c_str()
private:
    basic_string<Ch>* ps;
    size_type pos;
    size_type n;
};



Példa 42
=========

template<class Ch>
Basic_substring<Ch>::Basic_substring(basic_string<Ch>& s, const basic_string<Ch>& s2)
    :ps(&s), n(s2.length())
{
    pos = s.find(s2);
}

template<class Ch>
Basic_substring<Ch>& Basic_substring<Ch>::operator=(const basic_string<Ch>& s)
{
    ps->replace(pos,n,s);   // write through to *ps
    return *this;
}

template<class Ch> Basic_substring<Ch>::operator basic_string<Ch>() const
{
    return basic_string<Ch>(*ps,pos,n); // copy from *ps
}



Példa 43
=========

typedef Basic_substring<char> Substring;

void f()
{
    string s = "Mary had a little lamb";
    Substring(s,"lamb") = "fun";
    Substring(s,"a little") = "no";
    string s2 = "Joe" + Substring(s,s.find(' '),string::npos);
}



Példa 44
=========

template<class Ch, class Tr = char_traits<Ch>, class A = allocator<Ch> >
class basic_string {
public:
    // ...
    // size, capacity, etc. 
    // 
    size_type size() const;                     // number of characters
    size_type max_size() const;                 // largest possible string
    size_type length() const { return size(); }
    bool empty() const { return size()==0; }

    void resize(size_type n, Ch c);
    void resize(size_type n) { resize(n,Ch()); }

    size_type capacity() const;                 // like vector: 
    void reserve(size_type res_arg = 0);        // like vector
    allocator_type get_allocator() const;
};



Példa 45
=========

template<class Ch, class Tr, class A>
basic_istream<Ch,Tr>& operator>>(basic_istream<Ch,Tr>&, basic_string<Ch,Tr,A>&);

template<class Ch, class Tr, class A>
basic_ostream<Ch,Tr>& operator<<(basic_ostream<Ch,Tr>&,const basic_string<Ch,Tr,A>&);

template<class Ch, class Tr, class A>
basic_istream<Ch,Tr>& getline(basic_istream<Ch,Tr>&, basic_string<Ch,Tr,A>&, Ch eol);

template<class Ch, class Tr, class A>
basic_istream<Ch,Tr>& getline(basic_istream<Ch,Tr>&, basic_string<Ch,Tr,A>&);



Példa 46
=========

template<class Ch, class Tr, class A>
void swap(basic_string<Ch,Tr,A>&, basic_string<Ch,Tr,A>&);



Példa 47
=========

char* strcpy(char* p, const char* q);       // copy from q into p (incl. terminator)
char* strcat(char* p, const char* q);       // append from q to p (incl. terminator)
char* strncpy(char* p, const char* q, int n);   // copy n char from q into p
char* strncat(char* p, const char* q, int n);   // append n char from q to p

size_t strlen(const char* p);   // length of p (not counting the terminator)

int strcmp(const char* p, const char* q);       // compare: p and q
int strncmp(const char* p, const char* q, int n);   // compare first n char

char* strchr(char* p, int c);               // find first c in p
const char* strchr(const char* p, int c);
char* strrchr(char* p, int c);              // find last c in p
const char* strrchr(const char* p, int c);
char* strstr(char* p, const char* q);       // find first q in p
const char* strstr(const char* p, const char* q);

char* strpbrk(char* p, const char* q);      // find first char from q in p
const char* strpbrk(const char* p, const char* q);

size_t strspn(const char* p, const char* q);    // number of char in p before any char in q
size_t strcspn(const char* p, const char* q);   // number of char in p before a char not in q



Példa 48
=========

void f(const char* pcc, char* pc)   // C++
{
    *strchr(pcc,'a') = 'b'; // error: cannot assign to const char
    *strchr(pc,'a') = 'b';  // ok, but sloppy: there might not be an 'a' in pc
}



Példa 49
=========

char* strchr(const char* p, int c); /* C standard library function, not C++ */

void g(const char* pcc, char* pc)   /* C, will not compile in C++ */
{
    *strchr(pcc,'a') = 'b'; /* converts const to non-const: ok in C, error in C++ */
    *strchr(pc,'a') = 'b';  /* ok in C and C++ */
}



Példa 50
=========

void f(char* p, char* q)
{
    if (p==q) return;       // pointers are equal
    if (strcmp(p,q)==0) {   // string values are equal
        int i = strlen(p);  // number of characters (not counting the terminator)
        // ...
    }
    char buf[200];
    strcpy(buf,p);          // copy p into buf (including the terminator)
                        // sloppy: will overflow some day.
    strncpy(buf,p,200);     // copy 200 char from p into buf
                        // sloppy: will fail to copy the terminator some day.
    // ...
}



Példa 51
=========

double atof(const char* p); // convert p to double
int atoi(const char* p);        // convert p to int
long atol(const char* p);       // convert p to long



Példa 52
=========

int isalpha(int);   // letter: 'a'..'z' 'A'..'Z' in C locale (_string.traits_, _io.locale_)
int isupper(int);   // upper case letter: 'A'..'Z' in C locale (_string.traits_, _io.locale_)
int islower(int);   // lower case letter: 'a'..'z' in C locale (_string.traits_, _io.locale_)
int isdigit(int);       // decimal digit: '0'..'9'
int isxdigit(int);  // hexadecimal digit: '0'..'9' or 'a'..'f' or 'A'..'F'
int isspace(int);   // ' ' '\t' '\v' return newline formfeed
int iscntrl(int);       // control character (ASCII 0..31 and 127)
int ispunct(int);   // punctuation: none of the above
int isalnum(int);   // isalpha() | isdigit()
int isprint(int);   // printable: ascii ' '..'~'
int isgraph(int);   // isalpha() | isdigit() | ispunct()

int toupper(int c); // uppercase equivalent to c
int tolower(int c); // lowercase equivalent to c



Példa 53
=========

if (('a'<=c && c<='z') || ('A'<=c && c<='Z')) { // alphabetic
    // ...
}