Chapter 8 Strings and Vectors (8.1 and 8.2) An Array of characters • Defined as: char firstName[20]; char firstName[] = {‘T’, ‘i’, ‘m’}; // an array of 3 characters char firstName[20] = “Tim”; // an array of 4 characters ‘T’, ‘i’, ‘m’ and ‘\0’ • ‘\0’ is called NULL character. • The variable firstName in the third example is called a c-string variable. An Array Type for Strings • cstring: an array of characters ending with the null character ‘\0’. • NULL character: – is a single character. – used in functions defined in cstring library to denote the end of the string. – is a flag to signify the end of the string. This is call delimiter. C-String Notes • A CString is signified by double quotes. • The length of the CString is one less than the size. – Therefore, we must always make sure the CString length is large enough to hold ‘\0’ or we overrun string bounds. – char w[4] ; can only hold 3 characters and ‘\0’ • It may be initialized at declaration. char name[5] = “Bill”; • When the compiler initializes a string constant, the null character is added automatically. • A CString variable is NOT the same as an array of char-that does not have a null character. C-String Notes (cont.) • When we build the string ourselves we must add the ‘\0’ char name[5]; for ( int j = 0; j < 4; j++) cin>>name[j]; name[4] = ‘\0’; • ‘a’ is a character constant whose size = 1 • “a” is a string constant whose size 2. • When inputting into a CString, do not destroy the ‘\0’; char oops[3] = “goo”; //NOT ok char ohno[4] = “goo”; ohno[3] = ‘s’; //NOT ok • Can only assign string constant during variable declaration. • Cannot use the assignment operator. char yourName[20], myName[20]=“Timothy”; yourName = myName; // illegal (Syntax error) • Since CStrings are arrays, you must copy element by element. Predefined Functions for C-String • • #include <cstring.h> strcpy(dest, src): copies string into destination string. – – – – • BE CAREFUL! If src string is too long it will overwrite the next storage space. dest: (destination) must be a cstring variable. src: (source) a string constant or a variable Ex: char name[20], myName[20]=“Timothy”; strcpy(name, “Robert”); // name “Robert” strcpy(name, myName); // name “Timothy” strncpy(dest,src, n): is the same as strcpy except that the number of characters copied is limited to n. strncpy(name, myName, 3); // name “Tim” • strcat(dest, src) copies the second string onto the end of the first one. – – – – Doesn’t check for length. dest: (destination) must be a cstring variable. src: (source) a string constant or a variable Ex: char fName[20]=“Timothy” , lName[20]=“Mai”; strcat(fName, lName); // fName “TimothyMai” Predefined Functions for C-String (cont.) • strncat(strvar, string, n) is the same as strcat except that at most n characters are copied. strcat(lName, “, ”); // lName “Mai, ” strncat(lName, fName, 3); // lName “Mai, Tim” • strcmp(s1, s2) compares 2 strings (used ASCII values) and returns: – – – – – – • A negative value if s1<s2, b a 0 if s1=s2 or A positive value if s1>s2. Value is the difference in first 2 elements that differ. b e strcmp(“band”, “bend”) returns -4. Ex: If yourName and myName are the same???. if(strcmp (yourName, myName) == 0) Ex: If yourName and myName are NOT the same???. if(strcmp (yourName, myName) != 0) or if(!strcmp (yourName, myName)) d n d strncmp(s1,s2, n) is the same as strcmp except it compares up to n characters. strncmp(“band”, “bend”, 1) returns 0. strncmp(“band”, “bend”, 2) returns -4. • n strlen(str) returns the length of the string (not the size!) strlen(“band”) returns 4. strlen(lName) returns 8. C-String Input and Output • cin reads a string up to a blank space. • Use getline to read blank space. – Syntax: cin.getline(CString_Var, Max_Characters + 1); – getline reads and stores a line of max characters and puts in the ‘\0’. – Does not stop at blanks. C-String-to-Number Conversions • Functions to use: – atoi(CStringVar): converts a C-String to an integer. – atol(CStringVar): converts a C-String to a long integer. – atof(CStringVar): converts a C-String to an float. – Ex: int x = atoi(“123”); double y = atof(“123.45”); • Need: #include <cstdlib> • If the conversion cannot be made, return 0. CString-to-Number Conversions and Robust Input • Robust Input: Guarding against improper input by always reading input in as characters/strings and converting to numbers. • Use CString_to_number functions in cstdlib: • Ex: char anInteger[10], aDouble[10]; cin >> anInteger >> aDouble; // get inputs from user as CStrings int x = atoi(anInteger); double y = atof(aDouble); The Standard string class • Problem with CString is that the string length is fixed. • String class allows for length to vary and eliminates the problems of strcpy and strcat. • You can directly compare, assign one string to another and concatenate two strings together. • String class does an automatic conversion of cstrings to strings when mixed. string overloaded operators • Use with <string> library Initialize using default constructor. #include <string> name and fName are initialized to using namespace std; empty string “” string name, fName, lName(“Mai”); • Assignment: = fName = “Timothy”; Initialize using parameterized constructor • Concatenate: +, += name = fName + “ ” ; name += lName; // lName is concatenated to the end of name getline() for string objects • Read characters from the input stream istream until an instance of the delimiter is encountered. Delimiter can be any character. istream& getline (istream& ins, string& strVar, char delimiter); • Read characters from the input stream istream until an instance of ‘\n’ is encountered. istream& getline (istream& ins, string& strVar); • Ex: string msg; getline (cin, msg, ‘\t’); getline (cin, msg, ‘\n’); getline (cin, msg); // same as getline (cin, msg, ‘\n’); Some member functions of class string (Constructors) • Default constructor: string str; // create empty string • Parameterized constructor: string str(“sample”); // create a string object with data “sample” • Copy constructor: string str1(str); // create a string object str1 which is the copy of str Some member functions of class string (Element Access) • length(): returns the length of a string string str(“Sample”); int len = str.length(); // len=6 • stringVar[i]: returns a read/write reference to the character at a specific position in the string. Does not check for illegal position. (If position is greater than the string length) char second = str[1]; // second = ‘a’ str[10] = ‘m’; // illegal index but it is ok since it is considered an array of characters • at(i): returns a read/write reference to the character at a specific position in the string. Check for illegal position. char second = str.at(1); // second = ‘a’ str.at(10) = ‘m’; // illegal index. Exception rasied Some member functions of class string (Assignment/Modifiers) • empty(): returns true if the string is empty (“”), false other wise. str.empty(); • insert(pos, string): inserts a string into the current one at position pos. string str1(“Hello World”), str2(“Beautiful ”); str1.insert(6, str2); //“Hello Beautiful World” • erase(pos, length): removes substring of size length, starting at position pos. str1.erase(6, 10); //“Hello World” Some member functions of class string (Comparison Operators) • Equality or Inequality: ==, != str1 == str2: returns if string str1 equals str2 str1 != str2: returns if string str1 differs from str2 • Lexicographical comparisons: <, <=, >, >= str1 < str2: returns if string str1 is less than string str2 (ASCII) str1 <= str2: returns if string str1 is less than or equal string str2 (ASCII) str1 > str2: returns if string str1 is greater than string str2 (ASCII) str1 >= str2: returns if string str1 is greater than or equal string str2 (ASCII) Some member functions of class string (Finds) • find(subString): returns index of the first occurrence of a sub-string in the current one. string str1(“Hello World”), str2(“Wor”); str1.find(str2); //returns 6 • find(subString, pos): returns index of the first occurrence of a sub-string in the current one, starting at position pos. string str1(“Hello World”), str2(“o”); str1.find(str2); //returns 4 str1.find(str2, 2); //returns 4 str1.find(str2, 5); //returns 7 str1.find(str2, 8); //returns string::npos or -1 • find_first_of(subString, pos): returns index of the first occurrence of any character from sub-string in the current one, starting at position pos. string str1(“Hello World”), str2(“abc”), str3(“abcd”); str1.find_first_of(str2); // returns string::npos or -1 str1.find_first_of(str3); // returns 10 String Example (Palindrome Testing) • A palindrome is a string that reads the same front to back as it does back to front. • Display 8.8 tests an input string to see if it is a palindrome. • Our palindrome test will: – discard all spaces and punctuations – consider uppercase and lower case versions of a letter to be the same. Palindrome Testing #include <iostream> #include <string> #include <cctype> using namespace std; void swap (char& v1, char& v2); // Interchange the values of V1 and V2 string reverse (const string& s); // Return a copy of s but with characters in reversed order. string removePunt (const string& s, const string& punt); //Returns a copy of s with any occurrences of characters in the string punt removed. string makeLower (const string& s); //Return a copy of s that has all uppercase characters changed to lowercase, //other characters unchanged. bool isPalindrome (const string& s); // Return true if s is a palindrome, fall otherwise. int main() { string str; cout << "Enter a candidate for palindrome test and press <ENTER>: " getline (cin, str); if (isPalindrome (str)) cout << "\"" << str << "\" is a palindrome."; else cout << "\"" << str << "\" is not a palindrome."; cout << endl; return 0; } Palindrome Testing (cont.) void swap (char& v1, char& v2) { char temp = v1; v1 = v2; v2 = temp; } string reverse (const string& s) { int start = 0, end = s.length(); string temp(s); while (start < end) { end--; swap (temp[start], temp[end]); start++; } return temp; } // Uses <cctype> and <string> string makeLower (const string& s) { string temp(s); for (int i=0; i < s.length(); i++) temp[i] = tolower(temp[i]); return temp; } string removePunt (const string& s, const string& punt) { string noPunt; // initialized to empty string int sLength = s.length(); int punctLength = punt.length(); for (int i=0; i < sLength(); i++) { string aChar = s.substr(i, 1); // A one-character string int location = punt.find(aChar, 0); if (location < 0 || location >= puntLength) noPunt += aChar; // aChar not in punt, so keep it } return no_punt; } bool isPalindrome (const string& s) { string punt(",;:.?!'\" "); // no space between characters, also include blank string str(s); str = makeLower(str); string lowerStr = removePunt(str, punt); return (lowerStr == reverse(lowerStr)); } CString and string conversions char aCString[] = "This is a CString"; string aString; aString = aCString; // OK since string class has a parameterized constructor with a CString parameter. aCString = aString; // ILLEGAL, compiling error strcpy (aCString, aString); // ILLEGAL, compiling error strcpy (aCString, aString.c_str()); // ok since function c_str() returns a CString aCString = aString.c_str(); // ILLEGAL, compiling error