#include #include using namespace std; main() { string a("abcd efg"); string b("xyz ijk"); string c; cout << a << " " << b << endl; // Output: abcd efg xyz ijk cout << "String empty: " << c.empty() << endl; // String empty: 1 // Is string empty? Yes it is empty. (TRUE) c = a + b; // concatenation cout << c << endl; // abcd efgxyz ijk cout << "String length: " << c.length() << endl; // String length: 15 cout << "String size: " << c.size() << endl; // String size: 15 cout << "String capacity: " << c.capacity() << endl; // String capacity: 15 cout << "String empty: " << c.empty() << endl; // String empty: 0 // Is string empty? No it is NOT empty. (FALSE) string d = c; cout << d << endl; // abcd efgxyz ijk // First character: a cout << "First character: " << c[0] << endl; // Strings start with index 0 just like C. string f(" Leading and trailing blanks "); cout << "String f:" << f << endl; cout << "String length: " << f.length() << endl; // String length: 37 cout << "String f:" << f.append("ZZZ") << endl; // String f: Leading and trailing blanks ZZZ cout << "String length: " << f.length() << endl; // String length: 40 string g("abc abc abd abc"); cout << "String g: " << g << endl; // String g: abc abc abd abc cout << "Replace 12,1,\"xyz\",3: " << g.replace(12,1,"xyz",3) << endl; // Replace 12,1,"xyz",3: abc abc abd xyzbc cout << g.replace(0,3,"xyz",3) << endl; // xyz abc abd xyzbc cout << g.replace(4,3,"xyz",3) << endl; // xyz xyz abd xyzbc cout << g.replace(4,3,"ijk",1) << endl; // xyz i abd xyzbc cout << "Find: " << g.find("abd",1) << endl; // Find: 6 cout << g.find("qrs",1) << endl; string h("abc abc abd abc"); cout << "String h: " << h << endl; cout << "Find \"abc\",0: " << h.find("abc",0) << endl; // Find "abc",0: 0 cout << "Find \"abc\",1: " << h.find("abc",1) << endl; // Find "abc",1: 4 cout << "Find_first_of \"abc\",0: " << h.find_first_of("abc",0) << endl; // Find_first_of "abc",0: 0 cout << "Find_last_of \"abc\",0: " << h.find_last_of("abc",0) << endl; // Find_last_of "abc",0: 0 cout << "Find_first_not_of \"abc\",0: " << h.find_first_not_of("abc",0) << endl; // Find_first_not_of "abc",0: 3 cout << "Find_first_not_of \" \": " << h.find_first_not_of(" ") << endl; // Find_first_not_of " ": 0 cout << "Substr 5,9: " << h.substr(5,9) << endl; // Substr 5,9: bc abd ab cout << "Compare 0,3,\"abc\": " << h.compare(0,3,"abc") << endl; // Compare 0,3,"abc": 0 cout << "Compare 0,3,\"abd\": " << h.compare(0,3,"abd") << endl; // Compare 0,3,"abd": -1 cout << h.assign("xyz",0,3) << endl; // xyz cout << "First character: " << h[0] << endl; // Strings start with 0 // First character: x } 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 String class functions: * Constructors: string sVar1("abc"); string sVar1(C-string); string sVar2(10," "); // Generate string initialized to 10 blanks. string sVar3(Var1,string-index); // Initialize with characters from string starting with index string-index. string sVar4(iterator-index-begin, iterator-index-end) * Destructor: Var.~string(); // Destructor * Replace: o Var.replace(beginning,end-position,string-class-variable) o Var.replace(beginning,end-position,C-char-variable) o Var.replace(beginning,end-position,string-class-variable,length) o Var.replace(beginning,end-position,integer-number,single-char) o Var.replace(beginning,end-position,new-beginning-porition,new-end-position) Code samples: string g("abc abc abd abc"); cout << g.replace(4,1,"ijk",3) << endl; string h("abc abc abd abc"); cout << h.replace(4,6,"ijk",3) << endl; string k("abc abc abd abc"); cout << k.replace(4,3,"ijk",3) << endl; string l("abc abc abd abc"); cout << k.replace(12,1,"xyz",3) << endl; Output: abc ijkbc abd abc - Beginning with the fourth index (character number 5) replace one character with three characters from the 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: o Val.find(const string& argument) Find first occurence of argument within string Val o find(const string& argument, size_type index) Find first occurence of argument within string Val starting search from position index. o find(const char* argument) o find(const char* argument, size_type index) o 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. List of operations: 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 ==, !=, <, <=, >, >= Var.compare(string) Compare strings. 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. Var.find() Var.rfind() Find first occurance of string or substring. Find last occurance of string or substring. Var.find_first_of() Var.find_last_of() Find strings and substrings. Var.find_first_not_of() Var.find_last_not_of() Find strings and substrings. Var.replace() Replace section of string with new characters. Var.substr() Return substring of text 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. 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 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. #include #include #include using namespace std; int main() { char *phrase1="phrase"; string phrase2("Second phrase"); char phraseA[128]; char *phraseB; strcpy(phraseA,phrase2.c_str()); phraseB = strstr(phrase2.c_str(),phrase1); printf("phraseA: %s\n",phraseA); printf("phraseB: %s\n",phraseB); printf("phrase2: %s\n",phrase2.c_str()); } 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 #include #include #include using namespace std; string int2string(const int& number) { ostringstream oss; oss << number; return oss.str(); } main() { int number=7878; string test="SSSSS"; test += int2string(number); cout << test << endl; } 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 #include #include #include using namespace std; main() { string test="AAA 123 SSSSS 3.141592654"; istringstream totalSString( test ); string string1, string2; int integer1; double PI; totalSString >> string1 >> integer1 >> string2 >> PI; cout << "Individual parsed variables:" << endl; cout << "First string: " << string1 << endl; cout << "First integer: " << integer1 << endl; cout << "Value of PI: " << PI << endl; } 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: while( getline(std::cin, sLine) ) { if( sLine.empty() ); // Ignore empty lines else { cout << sLine[0] << sLine[1] << endl; .... ... } } * Read lines from input file: #define SYS_CONFIG_FILE "/etc/file.conf" #include #include #include #include #include #include using namespace std; string::size_type posBeginIdx, posEndIdx; string::size_type ipos=0; string sLine, sValue; string sKeyWord; const string sDelim( ":" ); ifstream myInputFile(SYS_CONFIG_FILE, ios::in); if( !myInputFile ) { sError = "File SYS_CONFIG_FILE could not be opened"; return sError; // ERROR } while( getline(myInputFile,sLine) ) { if( sLine.empty() ); // Ignore empty lines else { posEndIdx = sLine.find_first_of( sDelim ); sKeyWord = sLine.substr( ipos, posEndIdx ); // Extract word posBeginIdx = posEndIdx + 1; // Beginning of next word (after ':') .... ... } } The String Class and Debugging in GDB: The first thing you will notice when using the GNU 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 or use string class funtions to print out the value of the string variable. #include #include using namespace std; // Helper routine ps to print a string class variable. void ps(string& s){ cout << s << endl; } int main() { string a("String A"); string b; b = "String B"; cout << "Hello!" << endl; } 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 2 #include 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 One may also 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