C-strings and C++ string Class Topics • • • • • • • C-Strings Library Functions for Working with C-Strings Conversions Between Numbers and Strings Character Testing Character Case Conversion Writing Your Own C-String Handling Functions C++ string Class Strings • C-string: array of characters terminated by NULL character • The C-string "Hi there!" would be stored in memory as shown: H 12-3 i t h e r e ! \0 Array of char • Array of char can be defined and initialized to a C-string char str1[20] = "hi there!"; • Array of char can be defined and later have a string copied into it char str2[20]; strcpy(str2, "hi there!"); 12-4 Pointer to char • Pointer to char can refer to C-strings defined as arrays of char char str[20] = "hi"; char *pStr = str; cout << pStr; // prints hi • Can dynamically allocate memory to be used for C-string using new 12-5 Library Functions for C-Strings (Requires #include <cstring>) • int strlen(char *str) // Returns length of a C-string: cout << strlen("hello"); // Prints: 5 12-6 const int LENGTH = 30; char line[LENGTH]; cout << "Enter a string (no more than " << LENGTH - 1 << " characters.)\n"; cin.getline(line, LENGTH); cout << << << << "The C-string read was " "\"" << line << "\"" " whose length was " << strlen(line) endl; strcpy • char name[20] = “Mary” // This is OK char name2[20]; name2 = “Nancy”; char name3[20]; strcpy(name3, “Nancy”); cout << name3; 12-8 // Now allowed // Copy // Prints Nancy strcpy • strcpy(char *dest, char *source) // Copies a string from a source address // to a destination address char name[15]; strcpy(name, "Deborah"); cout << name; // prints Deborah 12-9 strcat • strcat(char *dest, char *source) // Takes two C-strings as input. // Adds the contents of the second string to the // end of the first string: char str1[15] = "Good "; char str2[30] = "Morning!"; strcat(str2, str1); cout << str1; // prints: Good Morning! • No automatic bounds checking: programmer must ensure that str1 has enough room for result 12-10 strcmp • int strcmp(char *str1, char*str2) // Compares strings stored at two addresses • Returns a value: less than 0 if str1 precedes str2 equal to 0 if str1 equals str2 greater than 0 if str1 succeeds str2 12-11 strcmp • Often used to test for equality if(strcmp(str1, str2) == 0) cout << "equal"; else cout << "not equal"; • Also used to determine ordering of C-strings in sorting applications • Note that C-strings cannot be compared using == or > if (str1 > str2) -- this is not allowed (compares addresses of C-strings, not contents) • If 12-12 Swapping const int NAME_LENGTH = 20; char name1[NAME_LENGTH]; char name2[NAME_LENGTH]; char temp[NAME_LENGTH]; strcpy(name1, "William"); strcpy(name2, "Catherine"); cout << "Originally...\n"; cout << "Name1: " << name1 << endl; cout << "Name2: " << name2 << endl; 12-13 Swapping (cont.) if (strcmp(name1, name2) > 0) { strcpy(temp, name1); strcpy(name1, name2); strcpy(name2, temp); } cout << "\nAfter switch...\n"; cout << "Name1: " << name1 << endl; cout << "Name2: " << name2 << endl; 12-14 Character Testing Requires #include <cctype> FUNCTION MEANING isalpha() true if arg. is a letter, false otherwise isalnum() true if arg. is a letter or digit, false otherwise isdigit() true if arg. is a digit 0-9, false otherwise islower() true if arg. is lowercase letter, false otherwise 12-15 Character Testing Require #include<cctype> FUNCTION MEANING isprint() true if arg. is a printable character, false otherwise ispunct() true if arg. is a punctuation character, false otherwise isupper() true if arg. is an uppercase letter, false otherwise isspace() true if arg. is a white space character, false otherwise 12-16 C++ String Class The C++ string Class • The string class offers several advantages over C-style strings: large body of member functions overloaded operators to simplify expressions • Requires #include <string> 12-18 string class constructors • string() • string(string str) initializes string object with str • string(char *cstr) initializes string ojbect with C-string • Various other constructors www.cplusplus.com 12-19 String Class Member Functions • int find(string str) // returns the position of str in the string object • int find (char ch) // returns the position of ch in the string object • int find (string str, int x) // returns the position of str beyond x • int find (ch ch, intx) // returns the position of ch beyond String Class Member Functions (cont.) • void insert (int x, string str) // inserts str at position x • void insert (int x, char ch) // inserts char at position x • string replace(int pos, int n, string str) // replaces n characters starting at pos with // substring str • Other member functions www.cplusplus.com Overloaded string Operators OPERATOR >> << = += MEANING reads whitespace-delimited strings into string object outputs string object to a stream assigns string on right to string object on left appends string on right to end of contents of string on left 12-22 Overloaded string Operators (continued) OPERATOR + [] >, >=, <, <=, ==, != MEANING Returns concatenation of the two strings references character in string using array notation relational operators for string comparison. Return true or false 12-23 Overloaded string Operators string word1, phrase; string word2 = " Dog"; cin >> word1; // user enters "Hot" // word1 has "Hot" phrase = word1 + word2; // phrase has // "Hot Dog" phrase += " on a bun"; for (int i = 0; i < 16; i++) cout << phrase[i]; // displays // "Hot Dog on a bun" 12-24 Swapping Two Strings string name1 = "William"; string name2 = "Catherine"; string temp; cout << "Originally...\n"; cout << "Name 1: " << name1 << endl; cout << "Name 2: " << name2 << endl; if (name1 > name2){ temp = name1; name1 = name2; name2 = temp; } cout << "\nAfter swap...\n"; cout << "Name 1: " << name1 << endl; cout << "Name 2: " << name2 << endl; Conversion to C-strings • data() and c_str() both return the Cstring equivalent of a string object • Useful when using a string object with a function that is expecting a C-string char greeting[20] = "Have a "; string str("nice day"); strcat(greeting, str.data()); 12-26 Modification of string objects • str.insert(int pos, string s) inserts s at position pos in str • Convert constructor for string allows a C-string to be passed in place of s string str("Have a day"); str.insert(7, "nice "); • insert is overloaded for flexibility 12-27 Modification of string objects • str.append(string s) appends contents of s to end of str • Convert constructor for string allows a C-string to be passed in place of s string str("Have a "); str.append("nice day"); • append is overloaded for flexibility 12-28 Your Turn (Formatting Number) • Problem: Design a function which formats a string like “1234567.89” to “$1,234,567.89”. • Plan: – Find the position dp of the decimal point – Starting at dp, count backwards and insert a comma every 3 places. – At position 0, insert ‘$’. Refinement dp 0 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 . 9 5 • dp position of decimal point in string pos dp • Loop (while dp is greater than 3) go back 3 places in the string insert ‘,’ there End Loop • Insert “$” at front of string Your Turn • Write a program which inputs a long text and counts the frequency of occurrence of each letter in the text. letters frequency 0 1 2 3 4 5 … 23 24 25 8 1 2 2 20 3 … 1 7 0 In Main() // Declarations const int MAX = 26; int frequency[MAX]; string text; cout << "Please enter a “ + “substantially long text.\n"; getline(cin, text); string input(text); // convert to // c-string letterFrequency(frequency, MAX, input); Letter Frequency • The quick brown fox jumps over the lazy dog. • Pack my box with five dozen liquor jugs. • Now is the time for all good people to come to the aid of their country. letterFrequency() void letterFrequency(int frequency[], int count, string input) { // Initialize requency for (int i = 0; i < count; i++){ frequency[i] = 0; } // Count frequency int length = input.length(); for (int i = 0; i < length; i++) { switch(input[i]) { case 'a': case 'A': frequency[0]++; break; case 'b': case 'B': frequency[1]++; break; letterFrequency() (cont.) case 'c': case 'C': case 'd': case 'D': case 'e': case 'E': . . . . . .; case 'x': case 'X': case 'y': case 'Y': case 'z': case 'Z': default:; } // switch } } frequency[2]++; break; frequency[3]++; break; frequency[4]++; break; frequency[23]++; break; frequency[24]++; break; frequency[25]++; break; String I/O • string str1; cin >> str1; // delimitted by // white-space cout << str1; • string str2; getline(cin, str2); // delimitted by // by eol Your Turn • Problem: – Input a long sentence and count the number of words. • Assumption: – All words are delimitted by a single space. In Main() • // Input text • // wordCount = countWords(text) • // Output results countWords() • int countWords(string text) Loop (while length > 0 && !done) ps position of ‘ ‘ in text If (ps = 0) done true End If Add one to count Replace first part of text with “” • End Loop