// CS1621 Fall 2005 // Strings in C++ #include #include // for old "c style" strings #include // for string class using namespace std; const int MAX_S = 12; int main() { int i; char str1[MAX_S], str2[MAX_S]; strcpy(str1, "0123456789"); strcpy(str2, str1); // copy one string to another cout << "str1: " << str1 << endl; cout << "str2: " << str2 << endl; cout << "'" << str1 << "' has a length of " << strlen(str1) << endl; // Primitive strings in C++ have a special character, '\0' to mark // where they end, so that they can be more easily input and output // in a nicely formatted way. Note that even though str1 is declared // to be a char array of length MAX_S (12), the length shown is only // 10, since the current "string" inside str1 has only 10 characters. if (strcmp(str1, str2) < 0) // char arrays can be compared using cout << str1 << " < " << str2; // the strcmp function. The idea else if (strcmp(str1, str2) == 0) // of this is similar to the // compareTo method in the Java cout << str1 << " == " << str2; // Comparable interface else cout << str1 << " > " << str2; cout << endl; char str3[4]; // One fundamental problem with the old c-style strcpy(str3, str1); // strings is that they did not check array cout << "str3: " << str3 << endl; // bounds during many of the operations. For // example, note that when printed out str3 // contains the entire string that was in str1, even though the // size of str3 is only 5. So where are the other characters // being stored? The answer comes when we print out str2! cout << "str2: " << str2 << endl; cout << "The characters in str2's array are\n"; for (i = 0; i < MAX_S; i++) { if (str2[i] == '\0') cout << " "; else cout << str2[i]; } cout << endl; // Now let's print out all of the strings, all from str3's point of // view. Note that the access is going "backward" due to the way the // variables are stored on the run-time stack. cout << "The first " << 2 * MAX_S + 10 << " chars from str3 are\n"; for (int i = 0; i < 2 * MAX_S + 10; i++) { if (str3[i] == '\0') cout << " "; else cout << str3[i]; } cout << endl; // The string class in C++ is somewhat safer than c strings, since // the methods restrict some access to the underlying data (which is // still basically an array of char). However, as you can see below, // the lack of array bound enforcement could still lead to problems. string realstring(str1); // c_str() method is for backward compatibility to c strings if (strcmp(realstring.c_str(), str1) == 0) cout << realstring << " == " << str1 << endl; // == is overloaded as well for compatibility if (realstring == str1) cout << realstring << " == " << str1 << endl; string rs2 = realstring; rs2.insert(4,"wacky"); cout << rs2 << endl; // Statement below throws an exception (out of bounds) // rs2.insert(25,"zany"); // However, the index operator [] does not check, so we can still // violate the bounds of the string, as shown below. However, now // the memory being accessed is in the heap rather than the run-time // stack. for (int i = 0; i < 60; i++) { cout << realstring[i] << ","; realstring[i] = 'x'; // uh oh, what am I changing? } cout << endl; }