现在的位置: 首页 > 综合 > 正文

C++ String class Examples and Tutorial

2018年05月12日 ⁄ 综合 ⁄ 共 16453字 ⁄ 字号 评论关闭

From http://www.yolinux.com/TUTORIALS/LinuxTutorialC++StringClass.html

 

Simple example of a program using string class and comparison with C char:

01 #include <string>
02 #include <iostream>
03 #include <string.h>   // Required by strcpy()
04 #include <stdlib.h>   // Required by malloc()
05  
06 using
namespace
std;
07  
08 main()
09 {
10    
string SS;    
// C++ STL string
11    
char
CC[17];  
// C character string (16 characters + NULL termination)
12                   
// Storage pre-allocated
13    
char
*CC2;    
// C character string. No storage allocated.
14  
15    
SS =
"This is a string"
;
16    
strcpy
(CC,
"This is a string"
);
17  
18    
CC2 = (
char
*)
malloc
(17);   
// Allocate memory for storage of string.
19    
strcpy
(CC2,
"This is a string"
);
20  
 
21    
cout << SS << endl;
22    
cout << CC << endl;
23    
cout << CC2 << endl;
24 }

Results:

This is a string
This is a string
This is a string

The C and C++ methods of managing a character data type are both valid
but we will see that the C++ string class offers more functionality and
convenience.
The STL string does not require memory to be pre-allocated nor allocated
manually.
The STL string class also provides many methods of string assignment.

Example of a program using many of the build-in functions of the string class:

 

01 #include <string>
02 #include <iostream>
03  
04 using
namespace
std;
05  
06 main()
07 {
08    
string a(
"abcd efg"
);
09    
string b(
"xyz ijk"
);
10    
string c;
11  
12    
cout << a <<
" "
<< b << endl;                       
// Output: abcd efg xyz ijk
13  
14    
cout <<
"String empty: "
    << c.empty()    << endl; 
// String empty: 1
15                                                          
// Is string empty? Yes it is empty. (TRUE)
16    
c = a + b;                                           
// concatenation
17    
cout << c << endl;                                   
// abcd efgxyz ijk
18    
cout <<
"String length: "
   << c.length()   << endl; 
// String length: 15
19    
cout <<
"String size: "
     << c.size()     << endl; 
// String size: 15
20    
cout <<
"String capacity: "
<< c.capacity() << endl; 
// String capacity: 15
21    
cout <<
"String empty: "
    << c.empty()    << endl; 
// String empty: 0
22                                                          
// Is string empty? No it is NOT empty. (FALSE)
23    
string d = c;
24    
cout << d << endl;                                   
// abcd efgxyz ijk
25  
26                                                          
// First character: a
27    
cout <<
"First character: "
<< c[0] << endl;         
// Strings start with index 0 just like C.
28  
29    
string f(
"    Leading and trailing blanks      "
);
30    
cout <<
"String f:"
<< f << endl;
31    
cout <<
"String length: "
<< f.length() << endl;     
// String length: 37
32    
cout <<
"String f:"
<< f.append(
"ZZZ"
) << endl;      
// String f:    Leading and trailing blanks      ZZZ
33    
cout <<
"String length: "
<< f.length() << endl;     
// String length: 40
34  
35    
string g(
"abc abc abd abc"
);
36    
cout <<
"String g: "
<< g << endl;                   
// String g: abc abc abd abc
37    
cout <<
"Replace 12,1,/"xyz/",3: "
<< g.replace(12,1,
"xyz"
,3) << endl; 
// Replace 12,1,"xyz",3: abc abc abd xyzbc
38    
cout << g.replace(0,3,
"xyz"
,3) << endl;              
// xyz abc abd xyzbc
39    
cout << g.replace(4,3,
"xyz"
,3) << endl;              
// xyz xyz abd xyzbc
40    
cout << g.replace(4,3,
"ijk"
,1) << endl;              
// xyz i abd xyzbc
41    
cout <<
"Find: "
<< g.find(
"abd"
,1) << endl;         
// Find: 6
42    
cout << g.find(
"qrs"
,1) << endl;
43  
44    
string h(
"abc abc abd abc"
);
45    
cout <<
"String h: "
<< h << endl;
46    
cout <<
"Find /"abc/",0: "
<< h.find(
"abc"
,0) << endl;
// Find "abc",0: 0
47    
cout <<
"Find /"abc/",1: "
<< h.find(
"abc"
,1) << endl;
// Find "abc",1: 4
48    
cout <<
"Find_first_of /"abc/",0: "
<< h.find_first_of(
"abc"
,0) << endl;
// Find_first_of "abc",0: 0
49    
cout <<
"Find_last_of /"abc/",0: "
<< h.find_last_of(
"abc"
,0) << endl;  
// Find_last_of "abc",0: 0
50    
cout <<
"Find_first_not_of /"abc/",0: "
<< h.find_first_not_of(
"abc"
,0) << endl; 
// Find_first_not_of "abc",0: 3
51    
cout <<
"Find_first_not_of /" /": "
<< h.find_first_not_of(
" "
) << endl; 
// Find_first_not_of " ": 0
52    
cout <<
"Substr 5,9: "
<< h.substr(5,9) << endl;      
// Substr 5,9: bc abd ab
53    
cout <<
"Compare 0,3,/"abc/": "
<< h.compare(0,3,
"abc"
) << endl; 
// Compare 0,3,"abc": 0
54    
cout <<
"Compare 0,3,/"abd/": "
<< h.compare(0,3,
"abd"
) << endl; 
// Compare 0,3,"abd": -1
55    
cout << h.assign(
"xyz"
,0,3) << endl;                  
// xyz
56    
cout <<
"First character: "
<< h[0] << endl;
// Strings start with 0 // First character: x
57  
58  
59 }

 


Compile: g++ program.cpp

[Potential Pitfall]
: In Red Hat Linux versions 7.x
one could omit the "using namespace std;
" statement. Use of this
statement is good programming practice and is required in Red Hat 8.0.

[Potential Pitfall]
: Red Hat 8.0 requires
the reference to "#include <iostream>
". Red Hat versions 7.x
used "#include <iostream.h>
". (Also fstream, ...)

 


 

Output: ./a.out

abcd efg xyz ijk
String empty: 1
abcd efgxyz ijk
String length: 15
String size: 15
String capacity: 15
String empty: 0
abcd efgxyz ijk
First character: a
String f: Leading and trailing blanks
String length: 37
String f: Leading and trailing blanks ZZZ
String length: 40
String g: abc abc abd abc
Replace 12,1,"xyz",3: abc abc abd xyzbc
xyz abc abd xyzbc
xyz xyz abd xyzbc
xyz i abd xyzbc
Find: 6
4294967295
String h: abc abc abd abc
Find "abc",0: 0
Find "abc",1: 4
Find_first_of "abc",0: 0
Find_last_of "abc",0: 0
Find_first_not_of "abc",0: 3
Find_first_not_of " ": 0
Substr 5,9: bc abd ab
Compare 0,3,"abc": 0
Compare 0,3,"abd": -1
xyz
First character: x


[Potential Pitfall]
: There have been some changes in the behavior of the string class from Red Hat 7.x to Red Hat 8.0:

  • The compare function arguments have changed from X.compare("string",int-1, int-2);
    to X.compare(int-1, int-2, "string");
  • The return value of the compare function call h.compare("abc",0,3)
    in 7.x was 12. In Red Hat 8.0 h.compare(0,3,"abc")
    it is 0.
  • String capacity function call "c.capacity()
    " is 15. The returned value in Red Hat 7.x was 16.

 


String class functions:

 

  • Constructors:

    1 string sVar1(
    "abc"
    );
    2 string sVar1(C-string-variable);
    3 string sVar2(10,
    " "
    ); 
    // Generate string initialized to 10 blanks.
    4 string sVar3(Var1, string-index); 
    // Initialize with characters from string starting with index string-index.
    5 string sVar4(iterator-index-begin, iterator-index-end)
  • Destructor:
    1 Var.~string();        
    // Destructor
  • Replace:
    • Var.replace(beginning,end-position,string-class-variable
      )
    • Var.replace(beginning,end-position,C-char-variable
      )
    • Var.replace(beginning,end-position,string-class-variable,length
      )
    • Var.replace(beginning,end-position,integer-number,single-char
      )
    • Var.replace(beginning,end-position,new-beginning-porition,new-end-position
      )

    Code samples:

    01 string g(
    "abc abc abd abc"
    );
    02 cout << g.replace(4,1,
    "ijk"
    ,3) << endl;
    03  
    04 string h(
    "abc abc abd abc"
    );
    05 cout << h.replace(4,6,
    "ijk"
    ,3) << endl;
    06  
    07 string k(
    "abc abc abd abc"
    );
    08 cout << k.replace(4,3,
    "ijk"
    ,3) << endl;
    09  
     
    10 string l(
    "abc abc abd abc"
    );
    11 cout << k.replace(12,1,
    "xyz"
    ,3) << endl;

    Output:


    abc ijkbc abd abc - Beginning with the 4th index (character number 5) replace one character with 3 characters from string "ijk"


    abc ijkd abc

    abc ijk abd abc

    abc abc abd xyzbc

     

  • Find: (also rfind(), find_first_of(), find_last_of(), find_first_not_of(), find_last_not_of())

    Arguments/parameters:

    • Val.find(const string& argument
      )


      Find first occurence of argument
      within string Val
    • find(const string& argument
      , size_type index
      )

      Find first occurence of argument
      within string Val
      starting search from position index
      .
    • find(const char* argument
      )
    • find(const char* argument
      , size_type index
      )
    • find(const char* argument
      , size_type index
      , size_type length
      )

      Find first occurence of argument
      within string Val
      starting search from position index
      and search for length
      number of characters.

 


 

STL C++ string functions:

Assuming declaration: string Var;

Function/Operation Description
Var = string2

Var.assign("string-to-assign
")
Assignment of value to string. When assigning a C "char" data type, first check if NULL to avoid failure/crash.
i.e.: if( szVar ) sVar.assign( szVar );

where szVar is a C "char *" data type and sVar is of type "string".
Var.swap(string2
)
swap(string1,string2
)
Swap with value held in string2.
Function swap will exchange contents of two string class variables.
Var += string2

Var.append()
Var.push_back()
Append string/characters.
Var.insert() Insert characters
Var.erase()
Var = ""
Clear string variable. No arguments necessary.
+ Concatenate
==, !=, <, <=, >, >= Compare strings.
Var.compare(string
)
Var.compare( size_t pos1, size_t len, string
) const;
Var.compare( size_t pos1, size_t len1, const string
, size_t pos2, size_t len2 ) const;
Compare strings. Returns int:

  • 0: if equal.
  • -1: Not equal. 1st non matching character in Var is less in value based on ASCII table than in compare string.
  • +1: Not equal. 1st non matching character is greater in value based on ASCII table.

Where string
is another STL string or null terminated C string.

Var.length() Return length of string. No arguments necessary. The methods length(), size()
and capacity()
all return the same value.
Var.size() Return length of string. No arguments necessary.
Var.capacity() Return length of string + 1. Red Hat 7.x. Red Hat
8.0+ returns the number of characters without the "+1". Number of
characters that can be held without re-allocation.
No arguments necessary.
Var.max_size() Returns a very large number. No arguments necessary.
Var.empty() Returns 1 if an empty string.
Returns 0 if not empty.
<< Output stream
>>
getline()
Input stream
Var.c_str() Returns C string pointer. C char string is null terminated. Do not free memory using this pointer!
Var.data() Returns C string pointer. C char string is NOT null terminated. Do not free memory using this pointer!
Var[]
Var.at(integer
)
Access individual characters. Return single character at specified position (integer).
Var.find(string
)
Var.find(string, positionFirstChar
)
Var.find(string, positionFirstChar, len
)
Find first occurance of string or substring. Returns int position of first occurance in string. Where len
is the length of the sequence to search for.
Returns string::npos
if not found.
i.e. if(Var.find("abc") == string::npos) cout << "Not found" << endl;
Var.rfind() Find last occurance of string or substring.
Var.find_first_of(string
, position)
Var.find_first_of( string
, size_t position, size_t len )
Find strings and substrings.
Where string
is another STL string or null terminated C string.
If position
= 0, than start at beginning of string.
Var.find_last_of() Find strings and substrings.
Var.find_first_not_of()
Var.find_last_not_of()
Find strings and substrings.
Var.replace(pos1, len1, string
)
Var.replace(itterator1, itterator2, const string
)
Var.replace(pos1, len1, string
, pos2, len2)
Replace section of string with new characters.

pos2 and len2 are given when using only a substring of string
.
Where string
is another STL string or null terminated C string.
Var.substr(pos, len) Return substring of text given a start position in string object and length.
Var.begin()
Var.end()
Iterators
Var.rbegin()
Var.rend()
Reverse iterators

Note that in most cases the string functions have been overloaded to accept
both string class arguments and C char variables.

 


ANSI C++ string class iterators:

Iterators provide the ability to access the individual characters in a string.

01 #include <iostream>
02 #include <string>
03 using
namespace
std;
04    
 
05 int
main()
06 {
07    
string alphabetLC=
"abcdefghijklmnopqrstuvwxyz"
;
08  
09    
string::const_iterator cii;
10    
int
ii;
11  
12    
for
(cii=alphabetLC.begin(); cii!=alphabetLC.end(); cii++)
13    
{
14       
cout << ii++ <<
" "
<< *cii << endl;
15    
}
16 }

This will print the integer position in the string followed by the letter
for all characters in the alphabet.

0 a
1 b
2 c
3 d
4 e
5 f
6 g
7 h
...
..

 


 

Iterator types:

  • string::traits_type
  • string::value_type
  • string::size_type
  • string::difference_type
  • string::reference
  • string::const_reference
  • string::pointer
  • string::const_pointer
  • string::iterator
  • string::const_iterator
  • string::reverse_iterator
  • string::const_reverse_iterator
  • string::npos

 


ANSI C++ string class and the C standard library:

The full use of the C standard library is available for use by utilizing the
".c_str" function return of the string class.

 

01 #include <strings.h>
02 #include <string>
03 #include <stdio.h>
04 using
namespace
std;
05    
 
06 int
main()
07 {
08    
char
*phrase1=
"phrase"
;
09    
string phrase2(
"Second phrase"
);
10    
char
  phraseA[128];
11    
char
  *phraseB;
12    
 
13    
strcpy
(phraseA,phrase2.c_str());
14    
phraseB =
strstr
(phrase2.c_str(),phrase1);
15  
16    
printf
(
"phraseA: %s/n"
,phraseA);
17    
printf
(
"phraseB: %s/n"
,phraseB);
18    
printf
(
"phrase2: %s/n"
,phrase2.c_str());
19 }  

Compile and run:

[prompt]$
 g++ test.cpp
[prompt]$ ./a.out
phraseA: Second phrase
phraseB: phrase
phrase2: Second phrase

 


Using ostringstream and an internal write:

In memory I/O string processing used as a data type conversion.
This can also be used to make use of formatting of output in memory.

File: int2string.cpp

01 #include <iostream>
02 #include <sstream>
03 #include <string>
04 using
namespace
std;
05  
 
06 string int2string(
const
int
& number)
07 {
08    
ostringstream oss;
09    
oss << number;
10    
return
oss.str();
11 }
12  
 
13 main()
14 {
15    
int
number=7878;
16    
string test=
"SSSSS"
;
17    
test += int2string(number);
18    
cout << test << endl;
19 }

Compile and run:

    [prompt]$
 g++ int2string.cpp
[prompt]$ a.out
SSSSS7878

[Potential Pitfall]
: Returned string value must
be used right away without other memory being set as string destructor will
free the memory associated with its contents. It is much safer for the function
to return a char
data type or pass the string reference as an argument.

Using istringstream and an internal read:

This is used to make use of reading and parsing a string in memory.
It will also allow data type conversion from a string to the type read.

File: test.cpp

01 #include <iostream>
02 #include <sstream>
03 #include <string>
04 using
namespace
std;
05  
 
06 main()
07 {
08    
string test=
"AAA 123 SSSSS 3.141592654"
;
09    
istringstream totalSString( test );
10    
string string1, string2;
11    
int
    integer1;
12    
double
PI;
13  
14    
totalSString >> string1 >> integer1 >> string2 >> PI;
15    
 
16    
cout <<
"Individual parsed variables:"
<< endl;
17    
cout <<
"First string:  "
<< string1   << endl;
18    
cout <<
"First integer: "
<< integer1  << endl;
19    
cout <<
"Value of PI:   "
<< PI        << endl;
20 }

Compile and run:

    [prompt]$
 g++ test.cpp
[prompt]$ a.out
Individual parsed variables:
First string: AAA
First integer: 123
Value of PI: 3.14159

 


Code snipets:

 

  • Read lines from standard input:

    01 while
    ( getline(std::cin, sLine) )
    02 {
    03    
    if
    ( sLine.empty() );                    
    // Ignore empty lines
    04    
    else
    05    
    {
    06       
    cout << sLine[0] << sLine[1] << endl;
    07       
    ....
    08       
    ...
    09    
    }
    10 }
  • Read lines from input file:
    01 #define SYS_CONFIG_FILE "/etc/file.conf"
    02 #include <string>
    03 #include <algorithm>
    04 #include <vector>
    05 #include <cctype>
    06 #include <iostream>
    07 #include <fstream>
    08  
    09 using
    namespace
    std;
    10  
    11 string::size_type posBeginIdx, posEndIdx;
    12 string::size_type ipos=0;
    13 string            sLine, sValue;
    14 string            sKeyWord;
    15 const
    string      sDelim(
    ":"
    );
    16  
    17 ifstream myInputFile(SYS_CONFIG_FILE, ios::in);
    18 if
    ( !myInputFile )
    19 {
    20    
    sError =
    "File SYS_CONFIG_FILE could not be opened"
    ;
    21    
    return
    sError;
    // ERROR
    22 }
    23  
    24 while
    ( getline(myInputFile,sLine) )
    25 {
    26    
    if
    ( sLine.empty() );                    
    // Ignore empty lines
    27    
    else
    28    
    {
    29       
    posEndIdx = sLine.find_first_of( sDelim );
    30       
    sKeyWord  = sLine.substr( ipos, posEndIdx );
    // Extract word
    31       
    posBeginIdx = posEndIdx + 1; 
    // Beginning of next word (after ':')
    32    
    ....
    33    
    ...
    34    
    }
    35 }
  • Strip blank characters:
    01 void
    02 stripLeadingAndTrailingBlanks(string& StringToModify)
    03 {
    04    
    if
    (StringToModify.empty())
    return
    ;
    05  
    06    
    int
    startIndex = StringToModify.find_first_not_of(
    " "
    );
    07    
    int
    endIndex = StringToModify.find_last_not_of(
    " "
    );
    08    
    string tempString = StringToModify;
    09    
    StringToModify.erase();
    10  
    11    
    StringToModify = tempString.substr(startIndex, (endIndex-startIndex+ 1) );
    12 }

 


The String Class and Debugging in GDB:

The first thing you will notice when using the C++ string class is that you can't
de-reference any of the string class variables directly with GDB, ddd,...
One must create a helper routine (for older versions of gdb)
or use string class funtions (newer versions of gdb) to print out the
value of the string variable.

01 #include <string>
02 #include <iostream>
03  
04 using
namespace
std;
05  
06 // Helper routine ps to print a string class variable.
07  
08 void
ps(string& s){ cout << s << endl; }
09  
10 int
main()
11 {
12    
string a(
"String A"
);
13    
string b;
14  
15    
b =
"String B"
;
16  
17    
cout <<
"Hello!"
<< endl;
18 }

Compile program with symbolic code for the debugger: g++ -g testprog.cpp

Start gdb
debugger: gdb ./a.out

(gdb) l 1,18                             - List lines 1 to 18


1 #include <string>
2 #include <iostream>
3
4 using namespace std;
5
6 // Helper routine ps to print a string class variable.
7
8 void ps(string& s){ cout << s << endl; }
9
10 int main()
11 {
12 string a("String A");
13 string b;
14
15 b = "String B";
16
17 cout << "Hello!" << endl;
18 }
(gdb) break 17
Breakpoint 1 at 0x804893b: file testprog.cpp, line 17.
(gdb) run
Starting program: /home/user1/a.out

Breakpoint 1, main () at testprog.cpp:17
17 cout << "Hello!" << endl;
(gdb) p a - Gdb can't de-reference string class variable "a"
$1 = {static npos = Cannot access memory at address 0x83a32d0
(gdb) call ps(a)
String A - Call helper function ps to print string conents.
(gdb) call ps(b)
String B
(gdb) c
Continuing.
Hello!

Program exited normally.
(gdb) quit

With newer versions of gdb, one may use built-in string class functions:

(gdb) p a.c_str()
$1 = 0x8049e34 "String A"
(gdb) p b.c_str()
$3 = 0x8049e4c "String B"
(gdb) p b.empty()
$2 = false
(gdb) p b.size()
$4 = 8

Dereference string
and wstring
using GDB macro functions.
See YoLinux.com GDB tutorial on dereferencing STL strings and containers
.

 


Tips:

 

  • The string class is NOT a native data type, it is an object class and thus
    can not be handled like the traditional pointer to variable in gdb.
  • One can pass strings by reference (i.e. argument declarations using (string& variable-name
    )

    ),
    by value (string variable-name
    )

    ,
    and by pointer (string *variable-name
    )

    .
  • When using a reference, one may mimic the protection of a variable that
    passing by value enables by using
    (const string& variable-name
    )

 


Links/Information:

 

抱歉!评论已关闭.