Notes_11 - Chapter 11 Strings & Multidimensional Arrays...

Info iconThis preview shows page 1. Sign up to view the full content.

View Full Document Right Arrow Icon
This is the end of the preview. Sign up to access the rest of the document.

Unformatted text preview: Chapter 11 Strings & Multidimensional Arrays Goals: To introduce the idea of character strings as arrays To demonstrate how character strings can be initialized To explore the stringrelated functions in cstring To illustrate how I/O works for character strings To examine the basics of multidimensional arrays in C++ Character Arrays To facilitate processing strings of characters representing text, C++ includes several features that enable char arrays to be manipulated more easily for input, output, and initialization. To take advantage of these features, remember one rule: THE LAST MEANINGFUL CHARACTER IN THE ARRAY MUST BE FOLLOWED BY THE NULL CHARACTER, `\0' CS 140 Chapter 10 Page 2 How Many Characters? The doublequotes around a constant character string hide the fact that each one actually ends with the null character. "Chicago" contains 8 characters "Reno\n\n" "" CS 140 contains 7 characters contains 1 character Chapter 10 Page 3 Character String Variables Since the null character is required after the last meaningful character in a string, the character array that's being used must be allocated one extra slot. char dayOfWeek[10]; "Wednesday" is the longest possible string, requiring ten characters, including the null character! CS 140 Chapter 10 Page 4 Character String Variable Initialization As with any other array in C++, character array variables may only use the assignment operator (=) when they're being initialized during variable declaration. ...but this is These are the same... different! char char char month[5] = "June"; month = "June"; month = {`J',`u',`n',`e',`\0'}; char month = {`J',`u',`n',`e'}; CS 140 Chapter 10 Page 5 Manipulating Individual Characters As with any other array in C++, individual array entries may be manipulated. Keep in mind that the null character (`\0') is used to signify where output should stop. #include <iostream> using namespace std; void main() { char phrase = "To be\0or not\0to be."; cout << phrase << endl << endl; phrase[5] = '\n'; cout << phrase << endl << endl; phrase[12] = ' '; cout << phrase << endl << endl; return; } Notice how the original string ended with a null character that didn't appear to exist in the initialization! Page 6 CS 140 Chapter 10 String Functions In cstring A number of functions that facilitate the manipulation of character strings reside in the cstring library. strcpy(targetStringVariable,sourceStringValue) Copies the sourceStringValue character string into the targetStringVariable (without checking to see if there's enough room) #include <iostream> #include <cstring> using namespace std; void main() { char word[11]; strcpy(word,"BOOK"); cout << word << "!!!" << endl << endl; strcpy(word,"DICTIONARY"); cout << word << "!!!" << endl << endl; strcpy(word,"ENCYCLOPEDIABRITTANNICA"); cout << word << "!!!" << endl << endl; return; } CS 140 Chapter 10 Page 7 strcat(targetStringVariable,sourceStringValue) Concatenates the sourceStringValue character string onto the end of the targetStringVariable (without checking to see if there's enough room) #include <iostream> #include <cstring> using namespace std; void main() { char first[25] = "I do not like"; char second = " green eggs"; char third = " and ham!"; cout << first << endl << endl; strcat(first,second); cout << first << endl << endl; strcat(first,third); cout << first << endl << endl; return; } CS 140 Chapter 10 Page 8 strlen(stringValue) Returns an integer equal to the length of stringVariable (stopping with the character just prior to the first null character) #include <iostream> #include <cstring> using namespace std; void main() { char simple = "Simon"; char hard = "Boiled\0Eggs"; char strange = "\0\0\0\0\0"; cout << << << cout << << << cout << << << return; } CS 140 Chapter 10 Page 9 "simple: " << simple "\tLength = " << strlen(simple) endl << endl; "hard: " << hard "\tLength = " << strlen(hard) endl << endl; "strange: " << strange "\tLength = " << strlen(strange) endl << endl; strcmp(firstStringValue,secondStringValue) Returns zero if the string values are equal, a negative integer if the first string value is "lexicographically" less than the second, and a positive integer if the second value is "lexicographically" less than the first #include <iostream> #include <cstring> using namespace std; void main() { char allcaps = char nocaps = char firstcap = char earlier = char later = "YES"; "yes"; "Yes"; "yen"; "Yet"; cout << "Compare \"" << allcaps << "\" to: " << '\"' << allcaps << "\" (" << strcmp(allcaps,allcaps) << ")\t" << '\"' << nocaps << "\" (" << strcmp(allcaps,nocaps) << ")\t" << '\"' << firstcap << "\" (" << strcmp(allcaps,firstcap) << ")\t" << '\"' << earlier << "\" (" << strcmp(allcaps,earlier) << ")\t" << '\"' << later << "\" (" << strcmp(allcaps,later) << ")" << endl << endl; ... Notice that uppercase letters are "lexicographically" less than lowercase letters. Page 10 CS 140 Chapter 10 A Large Example: Replacing Text ///////////////////////////////////////////////////////////////////////////////////// // This program takes a character string comprising a paragraph and gives the user // // repeated opportunities to substitute words within the paragraph. // ///////////////////////////////////////////////////////////////////////////////////// Notice that character strings, like all other #include <iostream> #include <cstdlib> arrays, may be passed by reference or by #include <cstring> constant-reference. using namespace std; void retrieveParagraph(char text); void showParagraph(const char statement); bool retrieveReplacementPair(char wordToDelete, char wordToInsert); void performReplacement(const char originalWord, const char replacementWord, char wholeText); const const const const MAX_TEXT_LENGTH = 600; MAX_WORD_LENGTH = 30; TABSIZE = 8; // RIGHT_MARGIN = 75; // // const int LEEWAY = 8; // // int int int int // The max. number of chars allowed in a paragraph. // The maximum number of chars allowed in a word. The num. of char spaces comprising a single tab. The number of spaces in a line of output after which a carriage return should occur. The num. of char spaces before the right margin where a convenient location for a carriage return is sought. CS 140 Chapter 10 Page 11 // The main function supervises the retrieval and display of the // // paragraph, as well as the repeated retrieval of replacement // // word pairs and the editing of the original paragraph. // void main() { char paragraph[MAX_TEXT_LENGTH]; // The text being edited. char oldWord[MAX_WORD_LENGTH]; // The word being eliminated. char newWord[MAX_WORD_LENGTH]; // The word being substituted. bool continueFlag; // Flag indicating if all editing is done. retrieveParagraph(paragraph); showParagraph(paragraph); continueFlag = retrieveReplacementPair(oldWord, newWord); while (continueFlag) { performReplacement(oldWord, newWord, paragraph); showParagraph(paragraph); continueFlag = retrieveReplacementPair(oldWord, newWord); } return; } Again, the function calls themselves do not include information about the type of the array, the dimension of the array, or even the fact that the variable is an array! Page 12 CS 140 Chapter 10 // Void function retrieveParagraph fills the text parameter // // with the characters that make up the paragraph to be edited. // void retrieveParagraph(char text) { strcpy(text, "\tDon Juan pointed directly to a boulder in front of us. "); strcat(text, "\"Look at the shadow of that boulder,\" he said. "); strcat(text, "\"The shadow is the boulder, and yet it isn\'t. "); strcat(text, "To observe the boulder in order to know what the boulder is, "); strcat(text, "is doing, but to observe the shadow is not-doing.\"\n"); strcat(text, "\t\"Shadows are like doors, the doors of not-doing. "); strcat(text, "You may say that there is movement in them, "); strcat(text, "or you may say that the lines of the world are shown in them, "); strcat(text, "or you may say that feelings come from them.\""); strcat(text, "\n\n\t\t\t\t\t-Carlos Castaneda\n\n"); return; } This could have been accomplished with a single strcpy call, but it would have required the code to be on a single line! To enhance readability, then a combination of strcat calls is used instead. CS 140 Chapter 10 Page 13 // Void function showParagraph outputs the paragraph in // // parameter statement. It attempts to satisfy the right // // margin requirement by invoking carriage returns // // whenever the current output line approaches that limit. // void showParagraph(const char statement) { int stmtIndex; // Position in paragraph of char now being examined. int currentColumn = 1; // Column of output screen affected by next cout stmt. char currentChar; // Char currently being examined for possible output. for (stmtIndex = 0; stmtIndex < (int)strlen(statement); stmtIndex++) { currentChar = statement[stmtIndex]; if ((currentChar != ' ') || ((currentChar == ' ') && (currentColumn != 1))) { cout << currentChar; if (currentChar == '\t') // Status of current currentColumn += TABSIZE; // output column is else if (currentChar == '\n') // adjusted based on currentColumn = 1; // which character else // is being output. currentColumn++; if ((currentColumn > RIGHT_MARGIN - LEEWAY) && ((currentChar == ' ') || (currentChar == '\t'))) { cout << endl; currentColumn = 1; } } } return; } // No blanks allowed // at the front of // an output line. // // // // // // When right margin is approached, a carriage return is executed when white space is found. To ensure that the character string isn't altered in this function, it's passed by constant-reference. Chapter 10 Page 14 CS 140 // Integer function retrieveReplacementPair queries the user regarding // whether or not more words will be substituted within the paragraph. // If so, the user is asked to enter the current and replacement strings. // In any case, a boolean is returned to the calling function, indicating // whether or not further editing is being done. bool retrieveReplacementPair(char wordToDelete, char wordToInsert) { char YorN; cout << "Would you like to edit the text? (Enter Y or N:) "; cin >> YorN; YorN = toupper(YorN); while ((YorN != 'Y') && (YorN != 'N')) { cout << "You must type Y for YES or N for NO:"; cin >> YorN; YorN = toupper(YorN); The toupper function, } if (YorN == 'N') return false; else { cout << "Enter the word to be changed: "; cin >> wordToDelete; cout << "Enter the replacement word: "; cin >> wordToInsert; cout << endl; return true; } } CS 140 // // // // // Both character strings are supposed to obtain values in this function, so they're passed by reference. defined in cstdlib, converts a lower-case alphabetic to upper-case. // // // // // It should be noted that this function has not been set up to handle whitespace (i.e., blanks, carriage returns, or) tabs within these words. The input operator assumes that white space marks the end of a character string that's being read. Chapter 10 Page 15 // Void function performReplacement cycles through the paragraph // // parameterized as wholeText and replaces every instance of the // // substring originalWord with the substring replacementWord, // // adjusting the rest of wholeText to accommodate any differences // // between the lengths of originalWord and replacementWord. // void performReplacement(const char originalWord, const char replacementWord, char wholeText) { int textIndex; // Iterative to traverse the entire paragraph being edited. int wordIndex; // Iterative to traverse the chars of the word being replaced. int replaceIndex; // Iterative to traverse the replacemt word during substitution. int suffixIndex; // Iterative to reinsert rest of paragraph after a substitution. int padIndex; // Iterative to pad the paragraph with ending null characters. bool matchesSoFar; // Flag indicating that the current substring of the paragraph // being examined matches the word which is being replaced. char dupText[MAX_TEXT_LENGTH]; // A copy of the paragraph; used to facilitate // editing without losing the original text. for (textIndex=0; textIndex <= (int)(strlen(wholeText)-strlen(originalWord)+1); textIndex++) { matchesSoFar = true; for (wordIndex = 0; wordIndex < (int)strlen(originalWord); wordIndex++) { if (originalWord[wordIndex] != wholeText[textIndex + wordIndex]) { matchesSoFar = false; break; } } The first two character string parameters won't receive new values in this function, but the third one (the original text that's being modified) might, so only the third parameter is passed by reference. Chapter 10 Page 16 CS 140 if (matchesSoFar) // Sought word exists as substring at pos. textIndex. { strcpy(dupText, wholeText); // Insert replacement word in duplicate paragraph at appropriate location for (replaceIndex=0; replaceIndex<(int)strlen(replacementWord); replaceIndex++) dupText[textIndex + replaceIndex] = replacementWord[replaceIndex]; // Insert rest of original paragraph after substitution location. for (suffixIndex = textIndex + strlen(originalWord); suffixIndex < (int)strlen(wholeText); suffixIndex++) dupText[suffixIndex-strlen(originalWord)+strlen(replacementWord)] = wholeText[suffixIndex]; // Insert null-zero characters at the end of the duplicate paragraph. for (padIndex = strlen(wholeText)-strlen(originalWord)+strlen(replacementWord); padIndex < MAX_TEXT_LENGTH; padIndex++) dupText[padIndex] = '\0'; // Copy the altered duplicate into the orig paragraph & adjust the iterative // to continue testing paragraph after the just-completed substitution. strcpy(wholeText, dupText); textIndex += (strlen(replacementWord) - 1); } } return; } If the replacement word is shorter than the original word, then the text must be padded at the end with null characters. No provision is made in the code if the reverse is true and the modified text becomes too long. CS 140 Chapter 10 Page 17 CS 140 Chapter 10 Page 18 Multidimensional Arrays It is possible to declare arrays of more than one dimension in C++. These arrays are essentially arrays of arrays... 52 rows & 7 columns, for a total of 364 double values! double hrsWorked[52][7]; int second[24][60][60]; 24 rows, 60 columns, & 60 layers for a total of 79200 integer values! CS 140 Chapter 10 Page 19 A Simple Example #include <iostream> using namespace std; void main() { int dozen[3][4] = {11,12,13,14,35,36,37,38,60,70,80,90}; int row; int col; for (row = 0; for (col = { cout << if (col cout else if cout row < 3; row++) 0; col < 4; col++) dozen[row][col]; != 3) << " | "; (row != 2) << endl << " | | | " << endl << "---+----+----+---" << endl << " | | | " << endl; The initialization of the twodimensional array loads the array one row at a time. } cout << endl << endl; return; } CS 140 Chapter 10 Page 20 A Large Example: Flight Schedules //////////////////////////////////////////////////////////// // This program reads data from an input file regarding a // // list of scheduled flights, and then outputs this data // // in a readable format to the monitor. // //////////////////////////////////////////////////////////// #include <iostream> #include <iomanip> #include <fstream> #include <cstring> using namespace std; const int MAX_NBR_FLIGHTS = 10; The prototypes may neglect to specify at most one of the dimensions of a multidimensional array parameter. Otherwise, the compiler will be unable to distinguish the dimensions. enum CityCode { Atlanta = 1, Chicago, Dallas, Denver, LosAngeles, NewYork, Seattle }; void loadData(int flightData[6], int &nbrOfRows); void computeTimes(const int data[6], int time, int nbrFlights); int timeChange(CityCode departCity, CityCode arriveCity); void outputChart(const int flyTable[6], const int minutes, int nbrRows); void outputFlightInfo(const int flightInfo, const int minutes); void convertCodeToCity(CityCode city, char cityString); void computeTime(int time, int &hour, int &min, char AMorPM); double computePrice(int nbrMinutes, int nbrMiles); CS 140 Chapter 10 Page 21 // The main function coordinates the retrieval of the flight // // data, the calculation of each flight's time in the air, // // and the output of the flight info in a readable format. // void main() { int numberOfFlights; int flightData[MAX_NBR_FLIGHTS][6]; int elapsedTime[MAX_NBR_FLIGHTS]; loadData(flightData, numberOfFlights); computeTimes(flightData, elapsedTime, numberOfFlights); outputChart(flightData, elapsedTime, numberOfFlights); return; } The main function "knows" that the flightData array has 10 rows and 6 columns. The loadData function "knows" that the array has 60 entries and 6 columns, so it "deduces" that there are 10 rows! // This function loads a two-dimensional array of integers // // with a prepackaged set of data about various flights. // void loadData(int flightData[6], int &nbrOfRows) { ifstream flightFile; int flightNbr; nbrOfRows = 0; flightFile.open("flightData.txt"); flightFile >> flightNbr; while (!flightFile.eof()) { flightData[nbrOfRows][0] = flightNbr; // Flight Number flightFile >> flightData[nbrOfRows][1]; // Source City Code flightFile >> flightData[nbrOfRows][2]; // Destination City Code flightFile >> flightData[nbrOfRows][3]; // Departure Time (Military) flightFile >> flightData[nbrOfRows][4]; // Arrival Time (Military) flightFile >> flightData[nbrOfRows][5]; // Distance In Miles nbrOfRows++; flightFile >> flightNbr; } return; } CS 140 Chapter 10 Page 22 // This function calculates the total amount of time, in minutes, // // between each flight's takeoff time and its arrival time. This // // data is stored in the parameterized array named time. // void computeTimes(const int data[6], int time, int nbrFlights) { int i, hours, minutes; for (i = 0; i < nbrFlights; i++) { hours = (data[i][4] / 100) - (data[i][3] / 100); if (hours < 0) hours += 24; hours += timeChange(CityCode(data[i][1]), CityCode(data[i][2])); minutes = (data[i][4] % 100) - (data[i][3] % 100); if (minutes < 0) { minutes += 60; The integer data in columns 1 & 2 of hours--; } that data array must be typecast to time[i] = 60 * hours + minutes; the enumerated CityCode type } return; before being passed to the } timeChange function. CS 140 Chapter 10 Page 23 // This function uses a seven-city numerical code to determine the // time difference between two cities, with positive numbers used // for east-to-west flights, and negative numbers for west-to-east // flights. Thus, for example, a NY-to-LA flight yields a result // of 3, while an LA-to-NY flight yields a result of -3. int timeChange(CityCode departCity, CityCode arriveCity) { int departTimeZone, arriveTimeZone; switch(departCity) { case(Atlanta): case(NewYork): case(Chicago): case(Dallas): case(Denver): case(LosAngeles): case(Seattle): } switch(arriveCity) { case(Atlanta): case(NewYork): case(Chicago): case(Dallas): case(Denver): case(LosAngeles): case(Seattle): } } // // // // // {departTimeZone {departTimeZone {departTimeZone {departTimeZone = = = = 3; 2; 1; 0; break;} break;} break;} break;} {arriveTimeZone {arriveTimeZone {arriveTimeZone {arriveTimeZone = = = = 3; 2; 1; 0; break;} break;} break;} break;} return (departTimeZone - arriveTimeZone); CS 140 Chapter 10 Page 24 // This function outputs the readable table of flight data to the monitor. // void outputChart(const int flyTable[6], const int minutes, int nbrRows) { int flight; cout.setf(ios::fixed); cout.setf(ios::showpoint); cout.precision(2); cout << << << << " "Flight "Number "-----ICARUS AIRLINES FLIGHT SCHEDULE" << endl << endl Departure Departure Arrival Arrival Ticket" << endl City Time City Time Price" << endl ----------------------------------" << endl; for (flight = 0; flight < nbrRows; flight++) outputFlightInfo(flyTable[flight], minutes[flight]); cout << endl << endl; return; } The outputFlightInfo function is being sent a single row of the flyTable 2-D array, as well as a single entry of the minutes 1-D array! CS 140 Chapter 10 Page 25 // This function outputs the flight information in the // parameterized array, using the parameterized integer // value to assist in computing the ticket price. void outputFlightInfo(const int flightInfo, const int { int hour; int min; char city[12]; char AMorPM[3]; double ticketPrice; cout << ' ' << flightInfo[0] << " "; // // // minutes) convertCodeToCity(CityCode(flightInfo[1]), city); cout << city << setw(14-strlen(city)) << ' '; computeTime(flightInfo[3], hour, min, AMorPM); cout << setw(2) << hour << ':'; (min < 10) ? (cout << '0' << min) : (cout << min); cout << AMorPM; convertCodeToCity(CityCode(flightInfo[2]), city); cout << " " << city << setw(15-strlen(city)) << ' '; computeTime(flightInfo[4], hour, min, AMorPM); cout << setw(2) << hour << ':'; (min < 10) ? (cout << '0' << min) : (cout << min); cout << AMorPM; ticketPrice = computePrice(minutes, flightInfo[5]); cout << " $" << ticketPrice << endl; return; } This function is unaware of the fact that its first parameter is actually a row of a 2-D array, and that its second parameter is actually an entry in a 1-D array! CS 140 Chapter 10 Page 26 // This function uses the numerical code associated with a particular // // city to yield the character string representing that city's name. // void convertCodeToCity(CityCode city, char cityString) { switch(city) { case(Atlanta) : {strcpy(cityString, "Atlanta"); break;} case(Chicago) : {strcpy(cityString, "Chicago"); break;} case(Dallas) : {strcpy(cityString, "Dallas"); break;} case(Denver) : {strcpy(cityString, "Denver"); break;} case(LosAngeles): {strcpy(cityString, "Los Angeles"); break;} case(NewYork) : {strcpy(cityString, "New York"); break;} case(Seattle) : {strcpy(cityString, "Seattle"); break;} } return; } // This function uses the military time represented in the parameter time // // to compute the civilian time in hours and minutes, as well as a string // // indicating whether that time is AM or PM. // void computeTime(int time, int &hour, int &min, char AMorPM) { (time < 1200) ? (strcpy(AMorPM, "AM")) : (strcpy(AMorPM, "PM")); hour = ((time/100 - 1) % 12 + 1); min = time % 100; return; } CS 140 Chapter 10 Page 27 // This function computes the price of a flight, using $2.50 // // per minute or $0.25 per mile, whichever is more expensive. // double computePrice(int nbrMinutes, int nbrMiles) { double timePrice, distancePrice, price; timePrice = 2.50 * nbrMinutes; distancePrice = 0.25 * nbrMiles; price = (timePrice > distancePrice) ? (timePrice) : (distancePrice); return price; } 1182 7498 9256 3037 6045 3572 4168 7 5 3 1 6 2 4 5 3 1 6 2 4 7 510 807 1250 1620 1854 2101 2319 721 1215 1529 1755 2000 2212 103 1134 1399 822 854 809 1021 1341 Input file flightData.txt Resulting output CS 140 Chapter 10 Page 28 ...
View Full Document

This note was uploaded on 08/26/2009 for the course CS 140 taught by Professor Staff during the Fall '08 term at Southern Illinois University Edwardsville.

Ask a homework question - tutors are online