class Menu
class OperationCounter
class RandomGenerator
class Stopwatch
class TextItems
1: /** @file utilities.h
2: Header file corresponding to utilities.cpp and utilities.obj, and
3: containing specifications for the facilities in namespace Scobey.
5: @author P. %Scobey
6: @date Monday, July 15, 2013
7: @version 2013.0
8: */
10: /**
11: @mainpage
12: This is the Fall, 2013 version of the documentation for the
13: instructor-supplied C++ utilities package to be used in CSCI 2341
14: and CSCI 2342. You will find here descriptions of some very useful
15: (time-saving) constant definitions, free functions, and classes.
16: It will take some time to become thoroughly familiar with all that
17: is available, but you will need to start using the package very soon
18: and you must continue to learn new facilities as the term progresses.
19: @section overview_sec Overview
20: There are three constant arrays containing names: one containing
21: 300 first names for females, one containing 300 first names for males,
22: and one containing 100 family names, all ranked in the order of name
23: frequency as observed in the United States and reported on the Internet
24: at these sites:
25: -# www.census.gov/genealogy/names/dist.female.first
26: -# names.mongabay.com/male_names_alpha.htm
27: -# en.wikipedia.org/wiki/List_of_most_common_surnames
29: <b>The source code that makes use of this utilities package must include
30: the <tt>utilities.h</tt> header file, and link to the corresponding object
31: file (which is named <tt>utilities.obj</tt> under Windows, and
32: <tt>utilities.o</tt> under Linux, for example). Note as well that the
33: package is enclosed in <tt>namespace Scobey</tt>.</b>
35: The package contains features in four categories, as listed below.
37: -# Fifteen free functions:<br />
38: Note that each member of the Read* sequence of free functions
39: in the list above provides the same kind of service: it prompts
40: for, and then reads in, from the standard input, a single value
41: of the type suggested by the function name. Only ReadInt and
42: ReadDouble contain error checking, and each continues to prompt
43: the user for a value of the correct type until a value of that
44: type is entered by the user (a potential infinite loop).
45: - ClearScreen
46: - DisplayOpeningScreen (implemented as an inline function)
47: - DisplayTextfile
48: - gcd
49: - isEven
50: - isOdd
51: - numberOfDigits
52: - Pause
53: - ReadChar
54: - ReadDouble
55: - ReadInt
56: - ReadNextLine
57: - ReadThisLine
58: - ReadString
59: - userSaysYes
60: -# Five utility classes:
61: - Menu
62: - OperationCounter
63: - RandomGenerator
64: - Stopwatch
65: - TextItems
66: -# Eleven named constants:
67: - CARD_DECK
68: - DAYS_OF_THE_WEEK_LONG
69: - DAYS_OF_THE_WEEK_SHORT
70: - DEFAULT_PROGRAMMER_INFO
71: - DEFAULT_PROGRAM_INFO
72: - MONTHS_OF_THE_YEAR_LONG
73: - MONTHS_OF_THE_YEAR_SHORT
74: - NAMES_3CHAR
75: - NAMES_FEMALE
76: - NAMES_MALE
77: - NAMES_FAMILY
78: -# One typedef (<em>deprecated</em>, since there should be no further need for this)
79: - String80
80: */
82: #ifndef UTILITIES_H
83: #define UTILITIES_H
85: #include <cstdlib>
86: #include <ctime>
87: #include <string>
88: #include <vector>
89: using std::cout;
90: using std::string;
91: using std::vector;
93: /**
94: Contains one typedef, eleven named constants,
95: fifteen free functions, and five utility classes.
96: */
97: namespace Scobey
98: {
100: //************************************************************************
101: //Typedef Section
103: typedef char String80[81];
104: /**<
105: Provides a legacy C-string type for holding up to 80 characters of text.
106: */
108: //
109: //
110: //************************************************************************
111: //Named Constant Section
113: const string CARD_DECK[] =
114: { "AS", "2S", "3S", "4S", "5S", "6S", "7S",
115: "8S", "9S", "TS", "JS", "QS", "KS",
116: "AH", "2H", "3H", "4H", "5H", "6H", "7H",
117: "8H", "9H", "TH", "JH", "QH", "KH",
118: "AD", "2D", "3D", "4D", "5D", "6D", "7D",
119: "8D", "9D", "TD", "JD", "QD", "KD",
120: "AC", "2C", "3C", "4C", "5C", "6C", "7C",
121: "8C", "9C", "TC", "JC", "QC", "KC"
122: };
123: /**<
124: Provides 2-character representations of each of the fifty-two cards
125: in a standard deck of cards.
126: */
129: const string DAYS_OF_THE_WEEK_LONG[] =
130: { "Monday", "Tuesday", "Wednesday", "Thursday",
131: "Friday", "Saturday", "Sunday"
132: };
133: /**<
134: Provides full names for days of the week.
135: */
138: const string DAYS_OF_THE_WEEK_SHORT[] =
139: { "Mon", "Tue", "Wed", "Thu",
140: "Fri", "Sat", "Sun"
141: };
142: /**<
143: Provides 3-letter abbreviations for days of the week.
144: */
147: const string DEFAULT_PROGRAM_INFO =
148: "Descriptive text required here is specificed elsewhere.";
149: /**<
150: Provides a placeholder value for a program title or brief description.
151: */
154: const string DEFAULT_PROGRAMMER_INFO =
155: "Lastname:Firstname:A00123456:CSC?????";
156: /**<
157: Provides a placeholder value for programmer identification information.
158: */
161: const string MONTHS_OF_THE_YEAR_LONG[] =
162: { "January", "February", "March", "April",
163: "May", "June", "July", "August",
164: "September", "October", "November", "December"
165: };
166: /**<
167: Provides full names for months of the year.
168: */
171: const string MONTHS_OF_THE_YEAR_SHORT[] =
172: { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
173: "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
174: };
175: /**<
176: Provides 3-letter abbreviations for months of the year.
177: */
180: const string NAMES_3CHAR[] =
181: { "Ace", "Ali", "Amy", "Ann", "Art",
182: "Ben", "Bob", "Cal", "Dan", "Del",
183: "Don", "Dot", "Eva", "Eve", "Fay",
184: "Gil", "Guy", "Hal", "Ian", "Jan",
185: "Jim", "Jon", "Kay", "Ken", "Kim",
186: "Liz", "Mac", "Min", "Nan", "Ora",
187: "Pam", "Red", "Rex", "Rik", "Rip",
188: "Rob", "Rod", "Rog", "Ron", "Roy",
189: "Sal", "Sam", "Sue", "Tad", "Tim",
190: "Tom", "Uma", "Val", "Wes", "Zig"
191: };
192: /**<
193: Provides fifty 3-character first names, some male and some female,
194: in alphabetical order.
195: */
198: const string NAMES_FAMILY[] =
199: { "Smith", "Johnson", "Williams", "Brown", "Jones",
200: "Miller", "Davis", "Garcia", "Rodriguez", "Wilson",
201: "Martinez", "Anderson", "Taylor", "Thomas", "Hernandez",
202: "Moore", "Martin", "Jackson", "Thompson", "White",
203: "Lopez", "Le", "Gonzalez", "Harris", "Clark",
204: "Lewis", "Robinson", "Walker", "Perez", "Hall",
205: "Young", "Allen", "Sanchez", "Wright", "King",
206: "Scott", "Green", "Baker", "Adams", "Nelson",
207: "Hill", "Ramirez", "Campbell", "Mitchell", "Roberts",
208: "Carter", "Phillips", "Evans", "Turner", "Torres",
209: "Parker", "Collins", "Edwards", "Stewart", "Flores",
210: "Morris", "Nguyen", "Murphy", "Rivera", "Cook",
211: "Rogers", "Morgan", "Peterson", "Cooper", "Reed",
212: "Bailey", "Bell", "Gomez", "Kelly", "Howard",
213: "Ward", "Cox", "Diaz", "Richardson", "Wood",
214: "Watson", "Brooks", "Bennett", "Gray", "James",
215: "Reyes", "Cruz", "Hughes", "Price", "Myers",
216: "Long", "Foster", "Sanders", "Ross", "Morales",
217: "Powell", "Sullivan", "Russell", "Ortiz", "Jenkins",
218: "Gutierrez", "Perry", "Butler", "Barnes", "Fisher"
219: };
220: /**<
221: Provides 100 family names (surnames), ranked in order of frequency
222: as found in the United States of America.
223: */
226: const string NAMES_FEMALE[] =
227: { "Mary", "Patricia", "Linda", "Barbara", "Elizabeth", "Jennifer",
228: "Maria", "Susan", "Margaret", "Dorothy", "Lisa", "Nancy",
229: "Karen", "Betty", "Helen", "Sandra", "Donna", "Carol",
230: "Ruth", "Sharon", "Michelle", "Laura", "Sarah", "Kimberly",
231: "Deborah", "Jessica", "Shirley", "Cynthia", "Angela", "Melissa",
232: "Brenda", "Amy", "Anna", "Rebecca", "Virginia", "Kathleen",
233: "Pamela", "Martha", "Debra", "Amanda", "Stephanie", "Carolyn",
234: "Christine", "Marie", "Janet", "Catherine", "Frances", "Ann",
235: "Joyce", "Diane", "Alice", "Julie", "Heather", "Teresa",
236: "Doris", "Gloria", "Evelyn", "Jean", "Cheryl", "Mildred",
237: "Katherine", "Joan", "Ashley", "Judith", "Rose", "Janice",
238: "Kelly", "Nicole", "Judy", "Christina", "Kathy", "Theresa",
239: "Beverly", "Denise", "Tammy", "Irene", "Jane", "Lori",
240: "Rachel", "Marilyn", "Andrea", "Kathryn", "Louise", "Sara",
241: "Anne", "Jacqueline", "Wanda", "Bonnie", "Julia", "Ruby",
242: "Lois", "Tina", "Phyllis", "Norma", "Paula", "Diana",
243: "Annie", "Lillian", "Emily", "Robin", "Peggy", "Crystal",
244: "Gladys", "Rita", "Dawn", "Connie", "Florence", "Tracy",
245: "Edna", "Tiffany", "Carmen", "Rosa", "Cindy", "Grace",
246: "Wendy", "Victoria", "Edith", "Kim", "Sherry", "Sylvia",
247: "Josephine", "Thelma", "Shannon", "Sheila", "Ethel", "Ellen",
248: "Elaine", "Marjorie", "Carrie", "Charlotte", "Monica", "Esther",
249: "Pauline", "Emma", "Juanita", "Anita", "Rhonda", "Hazel",
250: "Amber", "Eva", "Debbie", "April", "Leslie", "Clara",
251: "Lucille", "Jamie", "Joanne", "Eleanor", "Valerie", "Danielle",
252: "Megan", "Alicia", "Suzanne", "Michele", "Gail", "Bertha",
253: "Darlene", "Veronica", "Jill", "Erin", "Geraldine", "Lauren",
254: "Cathy", "Joann", "Lorraine", "Lynn", "Sally", "Regina",
255: "Erica", "Beatrice", "Dolores", "Bernice", "Audrey", "Yvonne",
256: "Annette", "June", "Samantha", "Marion", "Dana", "Stacy",
257: "Ana", "Renee", "Ida", "Vivian", "Roberta", "Holly",
258: "Brittany", "Melanie", "Loretta", "Yolanda", "Jeanette", "Laurie",
259: "Katie", "Kristen", "Vanessa", "Alma", "Sue", "Elsie",
260: "Beth", "Jeanne", "Vicki", "Carla", "Tara", "Rosemary",
261: "Eileen", "Terri", "Gertrude", "Lucy", "Tonya", "Ella",
262: "Stacey", "Wilma", "Gina", "Kristin", "Jessie", "Natalie",
263: "Agnes", "Vera", "Willie", "Charlene", "Bessie", "Delores",
264: "Melinda", "Pearl", "Arlene", "Maureen", "Colleen", "Allison",
265: "Tamara", "Joy", "Georgia", "Constance", "Lillie", "Claudia",
266: "Jackie", "Marcia", "Tanya", "Nellie", "Minnie", "Marlene",
267: "Heidi", "Glenda", "Lydia", "Viola", "Courtney", "Marian",
268: "Stella", "Caroline", "Dora", "Jo", "Vickie", "Mattie",
269: "Terry", "Maxine", "Irma", "Mabel", "Marsha", "Myrtle",
270: "Lena", "Christy", "Deanna", "Patsy", "Hilda", "Gwendolyn",
271: "Jennie", "Nora", "Margie", "Nina", "Cassandra", "Leah",
272: "Penny", "Kay", "Priscilla", "Naomi", "Carole", "Brandy",
273: "Olga", "Billie", "Dianne", "Tracey", "Leona", "Jenny",
274: "Felicia", "Sonia", "Miriam", "Velma", "Becky", "Bobbie",
275: "Violet", "Kristina", "Toni", "Misty", "Mae", "Shelly",
276: "Daisy", "Ramona", "Sherri", "Erika", "Katrina", "Claire"
277: };
278: /**<
279: Provides 300 female first names, ranked in order of frequency as found
280: in the United States of America.
281: */
284: const string NAMES_MALE[] =
285: { "James", "John", "Robert", "Michael", "William", "David",
286: "Richard", "Charles", "Joseph", "Thomas", "Christopher", "Daniel",
287: "Paul", "Mark", "Donald", "George", "Kenneth", "Steven",
288: "Edward", "Brian", "Ronald", "Anthony", "Kevin", "Jason",
289: "Matthew", "Gary", "Timothy", "Jose", "Larry", "Jeffrey",
290: "Frank", "Scott", "Eric", "Stephen", "Andrew", "Raymond",
291: "Gregory", "Joshua", "Jerry", "Dennis", "Walter", "Patrick",
292: "Peter", "Harold", "Douglas", "Henry", "Carl", "Arthur",
293: "Ryan", "Roger", "Joe", "Juan", "Jack", "Albert",
294: "Jonathan", "Justin", "Terry", "Gerald", "Keith", "Samuel",
295: "Willie", "Ralph", "Lawrence", "Nicholas", "Roy", "Benjamin",
296: "Bruce", "Brandon", "Adam", "Harry", "Fred", "Wayne",
297: "Billy", "Steve", "Louis", "Jeremy", "Aaron", "Randy",
298: "Howard", "Eugene", "Carlos", "Russell", "Bobby", "Victor",
299: "Martin", "Ernest", "Phillip", "Todd", "Jesse", "Craig",
300: "Alan", "Shawn", "Clarence", "Sean", "Philip", "Chris",
301: "Johnny", "Earl", "Jimmy", "Antonio", "Danny", "Bryan",
302: "Tony", "Luis", "Mike", "Stanley", "Leonard", "Nathan",
303: "Dale", "Manuel", "Rodney", "Curtis", "Norman", "Allen",
304: "Marvin", "Vincent", "Glenn", "Jeffery", "Travis", "Jeff",
305: "Chad", "Jacob", "Lee", "Melvin", "Alfred", "Kyle",
306: "Francis", "Bradley", "Jesus", "Herbert", "Frederick", "Ray",
307: "Joel", "Edwin", "Don", "Eddie", "Ricky", "Troy",
308: "Randall", "Barry", "Alexander", "Bernard", "Mario", "Leroy",
309: "Francisco", "Marcus", "Micheal", "Theodore", "Clifford", "Miguel",
310: "Oscar", "Jay", "Jim", "Tom", "Calvin", "Alex",
311: "Jon", "Ronnie", "Bill", "Lloyd", "Tommy", "Leon",
312: "Derek", "Warren", "Darrell", "Jerome", "Floyd", "Leo",
313: "Alvin", "Tim", "Wesley", "Gordon", "Dean", "Greg",
314: "Jorge", "Dustin", "Pedro", "Derrick", "Dan", "Lewis",
315: "Zachary", "Corey", "Herman", "Maurice", "Vernon", "Roberto",
316: "Clyde", "Glen", "Hector", "Shane", "Ricardo", "Sam",
317: "Rick", "Lester", "Brent", "Ramon", "Charlie", "Tyler",
318: "Gilbert", "Gene", "Marc", "Reginald", "Ruben", "Brett",
319: "Angel", "Nathaniel", "Rafael", "Leslie", "Edgar", "Milton",
320: "Raul", "Ben", "Chester", "Cecil", "Duane", "Franklin",
321: "Andre", "Elmer", "Brad", "Gabriel", "Ron", "Mitchell",
322: "Roland", "Arnold", "Harvey", "Jared", "Adrian", "Karl",
323: "Cory", "Claude", "Erik", "Darryl", "Jamie", "Neil",
324: "Jessie", "Christian", "Javier", "Fernando", "Clinton", "Ted",
325: "Mathew", "Tyrone", "Darren", "Lonnie", "Lance", "Cody",
326: "Julio", "Kelly", "Kurt", "Allan", "Nelson", "Guy",
327: "Clayton", "Hugh", "Max", "Dwayne", "Dwight", "Armando",
328: "Felix", "Jimmie", "Everett", "Jordan", "Ian", "Wallace",
329: "Ken", "Bob", "Jaime", "Casey", "Alfredo", "Alberto",
330: "Dave", "Ivan", "Johnnie", "Sidney", "Byron", "Julian",
331: "Isaac", "Morris", "Clifton", "Willard", "Daryl", "Ross",
332: "Virgil", "Andy", "Marshall", "Salvador", "Perry", "Kirk",
333: "Sergio", "Marion", "Tracy", "Seth", "Kent", "Terrance",
334: "Rene", "Eduardo", "Terrence", "Enrique", "Freddie", "Wade"
335: };
336: /**<
337: A named constant containing 300 male first names, 6 per line,
338: ranked in order of frequency as found in the United States.
339: */
341: //
342: //
343: //************************************************************************
344: //Free Function Section
346: void ClearScreen
347: (
348: int numLines = 25 //in
349: );
350: /**<
351: Clears the screen (the default output stream, which is assumed by
352: default to have 25 lines).
353: @return void
354: @param numLines The number of lines on the screen.
355: @pre None
356: @post <em>numLines</em> blank lines have been displayed on the standard
357: output stream (the screen).
358: */
361: void DisplayOpeningScreen
362: (
363: const string& programmerInfo = DEFAULT_PROGRAMMER_INFO, //in
364: const string& programInfo = DEFAULT_PROGRAM_INFO, //in
365: int numBlankLinesBefore = 11, //in
366: int numBlankLinesAfter = 12 //in
367: );
368: /**<
369: Displays an opening screen for any console program. The default display
370: shows a first line of programmer identification, the date and time of
371: the current program build on the second line, and a generic program
372: description on the third line of output. These three lines of output
373: are centered vertically, more or less, on an otherwise blank screen.
374: The idea is to keep the program description as short as possible
375: (preferably one or two lines), and to center vertically on the screen
376: all lines of output. To help accomplish these goals the user is permitted
377: to choose the number of blank lines to output both before and after the
378: lines containing information.
379: @return void
380: @param programmerInfo Text containing the programmer's ID info in the
381: appropriate form (specified elsewhere, but not in this documentation).
382: @param programInfo Text containing a brief (one-or-two-line)
383: description of the program.
384: @param numBlankLinesBefore The number of blank lines appearing on
385: the screen before the display of the contents of <em>programmerInfo</em>.
386: @param numBlankLinesAfter The number of blank lines appearing on the
387: screen after the display of the contents of <em>programInfo</em>.
388: @pre Note that default values are provided for all parameters and
389: the default values of <em>programmerInfo</em> and <em>programInfo</em>
390: are given by the named constants <em>DEFAULT_PROGRAMMER_INFO</em> and
391: <em>DEFAULT_PROGRAMMER_INFO</em> (respectively), which are described
392: elsewhere in this documentation. Here are the additional preconditions:
393: -# The standard input stream cin is empty.
394: -# Any newline character(s) required to begin a new line of output
395: have been included in the values of the string input parameter(s)
396: <em>programmerInfo</em> and/or <em>programInfo</em>.
397: @post
398: -# The contents of <em>programmerInfo</em> and <em>programInfo</em>
399: have been displayed, in that order, followed by a line similar to
400: the following:
401: <pre>
402: This executable was built on May 25 2007 at 23:47:51.
403: </pre>
404: There are no blank lines separating any of these lines of information,
405: but <em>numBlankLinesBefore</em> blank lines are output before the
406: contents of <em>programmerInfo</em> and <em>numBlankLinesAfter</em> blank lines
407: are output after the line containing the build date and time.
408: -# The program has paused after displaying a pause message, and the
409: user has pressed Enter.
410: */
413: void DisplayTextfile
414: (
415: const string& fileName, //in
416: int numberOfLinesPerPause = 23 //in
417: );
418: /**<
419: Displays a file of text numberOfLinesPerPause lines at a time.
420: This function allows the user to display any textfile on the
421: standard output and also lets the user decide how many lines
422: to display "between pauses", i.e., between the times when the
423: function pauses and waits for the user to press Enter to continue.
424: @return void
425: @param fileName The name of the file to be displayed.
426: @param numberOfLinesPerPause The number of lines displayed between
427: pauses.
428: @pre
429: <em>fileName</em> has been initialized.
430: @post
431: - Case 1 (typical): If <em>fileName</em> contains the name of an
432: existing and readable textfile in the current directory, or the full
433: pathname of an existing and readable textfile in some other accessible
434: directory, that file has been displayed on the screen numberOfLinesPerPause
435: lines at at time, preceded by the message
436: <pre>
437: ==================================================
438: The file display will begin when you continue after this pause.
439: And note that one blank line not in the file will appear after each pause.
440: Press Enter to continue ...
441: </pre>
442: and followed by this message:
443: <pre>
444: End of file has been reached.
445: Press Enter to continue ...
446: </pre>
447: In addition, after each group of lines has been displayed, the program
448: pauses and waits for the user to press Enter, with a message like the
449: following:
450: <pre>
451: =====Line immediately above is line ## of file name-of-file.
452: Press Enter to continue ...
453: </pre>
454: - Case 2 (error): If the file designated by <em>fileName</em> cannot
455: be opened, the function pauses and waits for the user to press Enter to
456: continue, with the message
457: <pre>
458: Error: \<\<name-of-file\>\> could not be opened.
459: Press Enter to continue ...
460: </pre>
461: and then returns.
462: */
465: int gcd
466: (
467: int a, //in
468: int b //in
469: );
470: /**<
471: Finds the greatest common divisor of two nonnegative integers,
472: at least one of which is strictly positive.
473: @return The greatest common divisor of the two input integers.
474: @param a A nonnegative integer.
475: @param b A nonnegative integer.
476: @pre Both <em>a</em> and <em>b</em> have been initialized with
477: nonnegative integer values, and at least one of <em>a</em> or
478: <em>b</em> is strictly positive.
479: @post No side effects.
480: */
483: bool isEven
484: (
485: int n //in
486: );
487: /**<
488: Determines if a positive integer is even.
489: @return <tt>true</tt> if n is an even integer, <tt>false</tt> if n is odd.
490: @param n The integer whose "evenness" is to be determined.
491: @pre <em>n</em> is a nonnegative integer.
492: @post No side effects.
493: */
496: bool isOdd
497: (
498: int n //in
499: );
500: /**<
501: Determines if a positive integer is odd.
502: @return <tt>true</tt> if n is an odd integer, <tt>false</tt> if n is even.
503: @param n The integer whose "oddness" is to be determined.
504: @pre <em>n</em> is a nonnegative integer.
505: @post No side effects.
506: */
509: int numberOfDigits
510: (
511: int n //in
512: );
513: /**<
514: Finds the number of digits in a positive integer.
515: @return The number of digits in the input integer.
516: @param n The integer whose digits are to be counted.
517: @pre <em>n</em> is a positive integer.
518: @post No side effects.
519: */
522: void Pause
523: (
524: int indentLevel = 0, //in
525: string message = "", //in
526: int pauseNumber = 0 //in
527: );
528: /**<
529: Causes the program to pause and wait for the user to press Enter
530: to continue, with default values for the indentation level, the
531: message supplying any additional information to the user, and the
532: pause number.
533: @return void
534: @param indentLevel The number of spaces to indent the first line
535: of each part of the output from the left margin.
536: @param message The message to be displayed, giving the reason for
537: this particular pause, if such a message is supplied.
538: @param pauseNumber The number of this particular pause, if pauses
539: are being numbered.
540: @pre
541: The input stream cin is empty.
542: @post
543: -# Each line of output produced by this function is automatically
544: indented <em>indentLevel</em> spaces, except for the second and any
545: subsequent lines of the text in <em>message</em>, which require a
546: newline character to start a new line.
547: -# If <em>pauseNumber</em> is 0 (the default value), there is no
548: corresponding output, while if <em>pauseNumber</em> is any positive
549: value (6 for example), a line like the following has been displayed
550: as the first line of output:
551: <pre>
552: This is pause #6.
553: </pre>
554: -# If <em>message</em> is non-empty, its content has been displayed
555: next, starting on the next line. An automatic newline is also inserted
556: following the text of <em>message</em>, so the text of <em>message</em>
557: itself need not (though it may) contain one or more newline characters.
558: -# As the last line of output, in all cases, the message
559: <pre>
560: Press Enter to continue ...
561: </pre>
562: has been displayed, with the cursor at the end of the line.
563: -# The user has pressed Enter.
564: */
567: void ReadChar
568: (
569: const string& userPrompt, //in
570: char& charValue //out
571: );
572: /**<
573: Gets a character (char) value from the user.
574: @param userPrompt Text of the prompt displayed to the user.
575: @param charValue Contains the character entered by the user.
576: @return void
577: @pre <em>userPrompt</em> has been initialized.
578: @post
579: -# The text in <em>userPrompt</em> has been displayed and the user
580: has entered a character (a value of type char), which is returned in
581: <em>charValue</em>. It is important to note that <strong>any</strong>
582: char value will be read, including any whitespace character.
583: -# The input stream cin is empty.
584: */
587: void ReadDouble
588: (
589: const string& userPrompt, //in
590: double& doubleValue //out
591: );
592: /**<
593: Gets a real (double) value from the user.
594: @return void
595: @param userPrompt Text of the prompt displayed to the user.
596: @param doubleValue Contains the real number entered by the user.
597: @pre
598: <em>userPrompt</em> has been initialized.
599: @post
600: -# The text in <em>userPrompt</em> has been displayed and the user
601: has entered a real number (a value of type <tt>double</tt>), which
602: is returned in <em>doubleValue</em>. If the user does not enter a
603: valid real number, the following message is displayed:
604: <pre>
605: Error: That was not a valid real number. Try again.
606: Press Enter to continue ...
607: </pre>
608: after which the prompt is displayed again and the user gets another
609: chance. This is essentially an infinite loop, so the user must eventually
610: enter a valid real number for the process to terminate normally.
611: -# The input stream cin is empty.
612: */
615: void ReadInt
616: (
617: const string& userPrompt, //in
618: int& intValue //out
619: );
620: /**<
621: Gets an integer (int) value from the user.
622: @return void
623: @param userPrompt Text of the prompt displayed to the user.
624: @param intValue Contains the integer value entered by the user.
625: @pre
626: <em>userPrompt</em> has been initialized.
627: @post
628: -# The text in <em>userPrompt</em> has been displayed and the user
629: has entered an integer (a value of type <tt>int</tt>), which is returned
630: in <em>intValue</em>. If the user does not enter a valid integer, the
631: following message is displayed:
632: <pre>
633: Error: That was not a valid integer. Try again.
634: Press Enter to continue ...
635: </pre>
636: after which the prompt is displayed again and the user gets another
637: chance. This is essentially an infinite loop, so the user must eventually
638: enter a valid integer value for the process to terminate normally.
639: -# The input stream cin is empty.
640: */
643: void ReadThisLine
644: (
645: const string& userPrompt, //in
646: string& lineValue //out
647: );
648: /**<
649: Reads the text entered by a user on the same line as the prompt.
650: @return void
651: @param userPrompt Text of the prompt displayed to the user.
652: @param lineValue Contains the text entered by the user.
653: @pre
654: <em>userPrompt</em> has been initialized.
655: @post
656: -# The text in <em>userPrompt</em> has been displayed and the user has
657: entered some text and then pressed Enter. All text entered on same line
658: as the prompt, after the prompt, (including all intermediate whitespace,
659: but not including the terminating newline character) is returned in
660: <em>lineValue</em>.
661: -# The input stream cin is empty.
662: */
665: void ReadNextLine
666: (
667: const string& userPrompt, //in
668: string& lineValue //out
669: );
670: /**<
671: Reads the text entered by a user on the line following the prompt.
672: @return void
673: @param userPrompt Text of the prompt displayed to the user.
674: @param lineValue Contains the line of text entered by the user.
675: @pre
676: <em>userPrompt</em> has been initialized.
677: @post
678: -# The text in <em>userPrompt</em> has been displayed and the
679: user has entered a line of input and then pressed Enter. The entire
680: line of input (including all intermediate whitespace, but not including
681: the terminating newline character) is returned in <em>lineValue</em>.
682: Note that in this case the input is entered on the line following
683: the prompt, while in each of the other Read* functions, the value is
684: entered by the user on the same line as the prompt for that value.
685: -# The input stream cin is empty.
686: */
689: void ReadString
690: (
691: const string& userPrompt, //in
692: string& stringValue //out
693: );
694: /**<
695: Gets a whitespace-delimited string value from the user.
696: @return void
697: @param userPrompt Text of the prompt displayed to the user.
698: @param stringValue Contains the string entered by the user.
699: @pre <em>userPrompt</em> has been initialized.
700: @post
701: -# The text in <em>userPrompt</em> has been displayed, and the user
702: has entered a string value and pressed Enter. The string value is
703: returned in <em>stringValue</em>. Note that the string read will be
704: terminated by any whitespace.
705: -# The input stream cin is empty.
706: */
709: bool userSaysYes
710: (
711: const string& question //in
712: );
713: /**<
714: Gets the user's yes-or-no answer to a single question.
715: @return <tt>true</tt> if the user answers "Yes" to the question asked,
716: and <tt>false</tt> otherwise.
717: @param question Text of the question the user is asked, including the
718: question mark.
719: @pre
720: -# <em>question</em> has been initialized.
721: -# The standard input stream is empty.
722: @post The text in <em>question</em> has been displayed, followed by
723: <tt>y/[n]</tt> and the user has responded by entering a character
724: and pressing Enter. The value <tt>true</tt> is returned if the user
725: responds positively to the question asked by entering a <tt>y</tt> or
726: a <tt>Y</tt>, or by entering any word beginning with either of these
727: letters. Entering any other letter or word, as well as simply
728: pressing the Enter key, will be interpreted as a negative response
729: and the return value will be <tt>false</tt>. The use of <tt>[n]</tt>
730: as part of the user prompt is meant to indicate to the user that simply
731: pressing Enter will generate a (default) response of "no". This is a
732: convention of reasonably widespread use in console applications.
733: */
736: //
737: //
738: //************************************************************************
739: //Utility Class Section
741: class Menu
742: /**
743: For displaying menus and getting user menu choices in console applications.
744: The <tt>%Menu</tt> class provides a convenient way for simple text-based
745: console programs to display for the user a menu of choices. A menu has a
746: title and up to 20 numbered options which are separated from the title by
747: a blank line when the menu is displayed. A menu knows what its range of
748: valid options is, and can get from the user a valid choice from that
749: range, or return an error value of -1 if the user fails to enter a valid
750: option number during three attempts (by default), or during some
751: client-chosen number of attempts.
752: */
753: {
754: public:
756: Menu();
757: /**<
758: Default constructor; creates a "blank" menu.
759: @pre None
760: @post A "blank" menu has been constructed which has
761: the (default) title <tt>"Empty Menu"</tt> and no options.
762: */
765: Menu
766: (
767: const string& menuTitle //in
768: );
769: /**<
770: Constructor for creating a menu with a user-supplied title
771: but no options.
772: @param menuTitle The text of the title for this menu.
773: @pre <em>menuTitle</em> has been initialized and does not exceed
774: 70 characters in length.
775: @post
776: - Case 1 (typical): A menu has been constructed with a title
777: given by the contents of <em>menuTitle</em>, and having 0 options.
778: - Case 2 (error): If an attempt was made to use a title whose
779: length exceeded the maximum length of 70 characters, the following
780: message has been displayed and the user has pressed Enter:
781: <pre>
782: ===== Error: %Menu title cannot exceed 70 characters in length.
783: The title
784: \<\<text_of_title_that_was_too_long_appears_here\>\>
785: was not added to the menu.
786: This menu has been given the following default title:
787: Empty %Menu
788: Press Enter to continue ...
789: </pre>
790: */
793: void setTitle
794: (
795: const string& menuTitle //in
796: );
797: /**<
798: Sets (or resets) the menu title.
799: @return void
800: @param menuTitle Contains the text of the title for the menu.
801: @pre <em>menuTitle</em> has been initialized and
802: <em>menuTitle.length() <= 70</em>.
803: @post
804: - Case 1 (typical): The text in <em>menuTitle</em> has been
805: assigned as the title of the menu.
806: - Case 2 (error): If an attempt was made to set a title which
807: exceeded the maximum length of 70 characters, the
808: following message has been displayed, and the user has pressed
809: Enter:
810: <pre>
811: ===== Error: %Menu title cannot exceed 70 characters in length.
812: The title
813: \<\<text_of_title_that_was_too_long_appears_here\>\>
814: was not added to the menu. Previous title remains unchanged.
815: Press Enter to continue ...
816: </pre>
817: In either case, the number of menu options is unchanged.
818: */
821: void addOption
822: (
823: const string& option //in
824: );
825: /**<
826: Adds a new option to the menu and assigns it the next available
827: option number.
828: @return void
829: @param option The text of the next option to be added to the menu.
830: @pre
831: The number of options on the menu is < 20.\n
832: <em>option</em> has been initialized and has length <= 70 characters.
833: @post
834: - Case 1 (typical): The number of menu options has been
835: incremented by 1 and the text in <em>option</em> has become the
836: option with the new option number.
837: - Case 2 (error): If the number of options was 20, then the
838: following message has been displayed and the user has pressed
839: Enter:
840: <pre>
841: ===== Error: Number of menu options cannot exceed 20.
842: Option \<\<text_of_option_goes_here\>\> not added.
843: Press Enter to continue ...
844: </pre>
845: - Case 3 (error): If an attempt was made to add an option which
846: exceeded the maximum length of 70 characters, the following
847: message has been displayed and the user has pressed Enter:
848: <pre>
849: ===== Error: %Menu option cannot exceed 70 characters in length.
850: The option
851: \<\<text_of_option_that_was_too_long_appears_here\>\>
852: was not added to the menu.
853: Press Enter to continue ...
854: </pre>
855: */
858: void display() const;
859: /**<
860: Displays a "centered" menu on the screen.
861: @return void
862: @pre The menu has been initialized.
863: @post The menu has been displayed on the screen, more or less
864: centered left-to-right and top-to-bottom, but with a slight
865: top-left bias. Note, however, that a blank menu, or a menu with
866: just a title, is displayed with its title left-justified and with
867: only the bias toward the top. Such a title is followed by a blank
868: line and the following 1-line message, which also starts at the
869: left margin:
870: <pre>
871: This menu currently has no options ...
872: </pre>
873: The (typical) display format is achieved in the following way:
874: - First, by displaying (1/2)(24-numMenuLines)+1 blank lines at
875: the bottom of the screen.
876: - Second, by arranging that column 38 (rather than column 40, of a
877: typical 80 line display) be the column about which the menu title
878: and the menu options are "centered" in the display.
879: */
882: int getChoice
883: (
884: int maxNumTries = 3, //in
885: string userPrompt =
886: "Enter the number of your menu choice here and press Enter: " //in
887: ) const;
888: /**<
889: Gets a menu choice from the user, or a default value if the user
890: fails to enter a valid menu choice before the permitted number
891: of attempts runs out.
892: @return The user's menu choice, or the default value of -1.
893: @param maxNumTries The maximum number of tries permitted to the
894: user to enter a valid menu choice.
895: @param userPrompt The text of the prompt to be used to ask the
896: user for a menu choice.
897: @pre
898: Typically, a menu has been initialized, and presumably
899: displayed, though in fact this is not technically a necessary
900: pre-condition for this function.
901: @post
902: - Case 1 (typical): A valid menu choice for the menu has been
903: entered by the user and returned.
904: - Case 2 (error): If a choice was sought from a blank menu, the
905: message
906: <pre>
907: ===== Error: The menu has no options from which to choose.
908: Press Enter to continue ...
909: </pre>
910: has been displayed and the user has pressed Enter.
911: - Case 3 (error): If an invalid menu choice has been entered, the
912: displayed message is:
913: <pre>
914: ===== Error: Sorry! Invalid response. Please try again:
915: </pre>
916: If <em>maxNumTries</em> unsuccessful attempts have
917: been made, the displayed message is:
918: <pre>
919: ===== Error: Sorry, but you only get \<\<maxNumTries\>\> chances.
920: Press Enter to continue ...
921: </pre>
922: and the user has pressed Enter, after which the value of -1
923: is returned. Note that if no prompt is supplied by the client,
924: the default prompt
925: <pre>
926: Enter the number of your menu choice here and press Enter:
927: </pre>
928: is displayed slighty left-of-center on the screen below the
929: menu.
930: Note as well that anything other than a valid menu choice for
931: the current menu will be read and rejected, including (for example)
932: a valid menu choice followed by extraneous characters, as well
933: as simply pressing Enter.
934: */
936: private:
937: static const int MAX_NUM_OPTIONS = 20;
938: static const int MAX_OPTION_LENGTH = 70;
939: static const int MAX_TITLE_LENGTH = 70;
941: int numOptions;
942: //Number of options currently on the menu.
944: vector<string> menuText;
945: //Contains the title and the options
946: //Both constructors set the size of menuText to 1+MAX_NUM_OPTIONS,
947: //which includes one row to hold the menu title, and MAX_NUM_OPTIONS
948: //rows to hold the options.
949: };
952: class OperationCounter
953: /**
954: For counting operations performed by an algorithm.
955: An object of the <tt>%OperationCounter</tt> class may be used to keep
956: a count of the number of each of several different kinds operations
957: performed during the application of an algorithm to a data set. The
958: operations that can be counted are the usual comparisons, exchanges,
959: and assignments that one might be interested in tracking, as well as
960: one other kind of operation chosen by the client. The client may also
961: supply a name for that "other" operation, and use that name in summary
962: output.
963: */
964: {
965: public:
967: OperationCounter();
968: /**<
969: Default constructor.
970: @pre None
971: @post A counter object has been constructed, with all operation
972: counters set to 0 and the name of the "other" operation set to
973: "Other Op".
974: */
977: void reset();
978: /**<
979: Resets all operation counters to zero and the name of the "other"
980: operation, if any, to an empty string.
981: @return void
982: @pre None
983: @post All counting data members have been reset to 0, and the
984: name of the "other" operation has been set to "Other Op".
985: */
988: void incrementAssignments
989: (
990: int numTimes = 1 //in
991: );
992: /**<
993: Increments the counter for the number of assignment operations.
994: @return void
995: @param numTimes The number of times the assignment counter
996: is to be incremented.
997: @return void
998: @pre None
999: @post The number of assignment operations has been incremented
1000: by the value of <em>numTimes</em>.
1001: */
1004: void incrementComparisons
1005: (
1006: int numTimes = 1 //in
1007: );
1008: /**<
1009: Increments the counter for the number of comparison operations.
1010: @return void
1011: @param numTimes The number of times the comparison counter
1012: is to be incremented.
1013: @pre None
1014: @post The number of comparison operations has been incremented
1015: by the value of <em>numTimes</em>.
1016: */
1019: void incrementExchanges
1020: (
1021: int numTimes = 1 //in
1022: );
1023: /**<
1024: Increments the counter for the number of exchange operations.
1025: @return void
1026: @param numTimes The number of times the exchange counter
1027: is to be incremented.
1028: @pre None
1029: @post The number of exchange operations has been incremented
1030: by the value of <em>numTimes</em>.
1031: */
1034: void incrementOtherOp
1035: (
1036: int numTimes = 1 //in
1037: );
1038: /**<
1039: Increments the counter for the number of "other" operations.
1040: @return void
1041: @param numTimes The number of times the counter of the
1042: "other" operation is to be incremented.
1043: @pre None
1044: @post The number of "other" operations has been incremented
1045: by the value of <em>numTimes</em>.
1046: */
1049: int getNumberOfComparisons() const;
1050: /**<
1051: Gets the number of comparison operations counted.
1052: @return The number of comparison operations counted.
1053: @pre None
1054: @post No side effects.
1055: */
1058: int getNumberOfExchanges() const;
1059: /**<
1060: Gets the number of exchange operations counted.
1061: @return The number of exchange operations counted.
1062: @pre None
1063: @post No side effects.
1064: */
1067: int getNumberOfAssignments() const;
1068: /**<
1069: Gets the number of assignment operations counted.
1070: @return The number of assignment operations counted.
1071: @pre None
1072: @post No side effects.
1073: */
1076: int getNumberOfOtherOp() const;
1077: /**<
1078: Gets the number of "other" operations performed.
1079: @return The number of "other" operations counted.
1080: @pre None
1081: @post No side effects.
1082: */
1085: void setNameOfOtherOp
1086: (
1087: string nameOfOtherOp //in
1088: );
1089: /**<
1090: Sets (or resets) the name of the "other" operation.
1091: @return void
1092: @param nameOfOtherOp Text for the name of the "other" operation.
1093: @pre <em>nameOfOtherOp</em> has been initialized.
1094: @post The value of <em>nameOfOtherOp</em> has been assigned as
1095: the name of the other operation.
1096: */
1099: string getNameOfOtherOp() const;
1100: /**<
1101: Gets the name of the "other" operation.
1102: @return The name of the "other" operation.
1103: @pre None
1104: @post The name of the "other operation" has been returned (and
1105: will be "Other Op" unless it has been set to something
1106: else with setNameOfOtherOp().
1107: */
1110: void displayNonZeroCounts() const;
1111: /**<
1112: Displays a summary of the counts for all operations actually performed
1113: (and which therefore have non-zero counts). This method would normally
1114: be called if only one or two operations were being counted and the
1115: user did not want to take up space in the output with zero counts
1116: for the other operations.
1117: @return void
1118: @pre None
1119: @post
1120: - Case 1: Whatever counts of comparisons, number of exchanges, number
1121: of assignments and/or the number of operations of the "other" kind (if
1122: applicable) have been recorded by counter object and are non-zero have
1123: been displayed as shown below. That is, the title is displayed, along
1124: with those lines corresponding to non-zero counts.
1125: <pre>
1126: Summary of Non-Zero Operation Counts
1127: Comparisons = #
1128: Exchanges = #
1129: Assignments = #
1130: Name of Other Operation = #
1131: </pre>
1132: - Case 2: If all counts are zero, the following message is displayed.
1133: <pre>
1134: Summary of Non-Zero Operation Counts
1135: No operations of any kind have been counted.
1136: </pre>
1137: */
1140: void displayAllCounts() const;
1141: /**<
1142: Displays a summary of the number of operations counted. This method
1143: would normally be used when the user desires to see all counts, even
1144: if some are (and are known to be) zero.
1145: @return void
1146: @pre None
1147: @post
1148: - Case 1: All operation counts are displayed in the format shown below.
1149: <pre>
1150: Summary of All Operation Counts
1151: Comparisons = #
1152: Exchanges = #
1153: Assignments = #
1154: Name of Other Operation = #
1155: </pre>
1156: - Case 2: If all counts are zero, the following message is displayed:
1157: <pre>
1158: Summary of All Operation Counts
1159: No operations of any kind have been counted.
1160: </pre>
1161: */
1164: private:
1165: int numComparisons;
1166: int numExchanges;
1167: int numAssignments;
1168: int numOtherOp;
1169: string nameOfOtherOp;
1170: };
1174: class RandomGenerator
1175: /**
1176: For generating pseudorandom integer, real, character and string values.
1177: The <tt>%RandomGenerator</tt> class can be used to generate pseudorandom
1178: values of the following types:
1179: - int values in a user-chosen range
1180: - double values in a user-chosen range
1181: - char values in a user chosen range
1182: - string values of a user chosen size, containing user-chosen characters
1183: */
1184: {
1185: public:
1187: RandomGenerator();
1188: /**<
1189: Default constructor, based on seed obtained from a call to the
1190: <tt>time()</tt> function. If a random generator constructed by
1191: this constructor is used, the sequence of random values will be
1192: different each time.
1193: @pre None
1194: @post The generator has been initialized with a random seed value
1195: obtained by a call to the <tt>time()</tt> function.
1196: */
1199: RandomGenerator
1200: (
1201: int userSeedValue //in
1202: );
1203: /**<
1204: Constructor based on a client-supplied seed. If a random generator
1205: constructed by this constructor is used, the <em>userSeedValue</em>
1206: used determines the sequence of random values obtained, and the same
1207: sequence of values can be obtained on a subsequent run by reusing
1208: the same <em>userSeedValue</em>. This same <em>userSeedValue</em> can
1209: be used to construct a new random generator object using this constructor,
1210: or to reset an already existing random generator object using the reset()
1211: method; either way, you get the same sequence of values as you did when
1212: that <em>userSeedValue</em> was employed previously.
1213: @param userSeedValue A seed value supplied by the client.
1214: @pre <em>userSeedValue</em> has been initialized.
1215: @post The generator has been initialized using a seed value
1216: (<em>userSeedValue</em>) supplied by the client.
1217: */
1220: void reset();
1221: /**<
1222: Resets the random generator using a seed obtained by a call to
1223: the <tt>time()</tt> function.
1224: @return void
1225: @pre None
1226: @post The generator has been re-initialized using a random seed
1227: value obtained by a call to the time function.
1228: */
1231: void reset
1232: (
1233: int userSeedValue //in
1234: );
1235: /**<
1236: Resets the random generator using a seed supplied by the client.
1237: @return void
1238: @pre userSeedValue has been initialized.
1239: @post The generator has been re-initialized using a seed value
1240: (userSeedValue) supplied by the client.
1241: */
1244: //
1245: //
1246: //********** Random int generators **********
1247: int getNext
1248: (
1249: int n //in
1250: );
1251: /**<
1252: Gets a pseudorandom integer in the range <em>[0,n)</em>.
1253: @return A pseudorandom int value in the range <em>[0,n)</em>.
1254: @param n A positive integer value.
1255: @pre <em>n</em> has been initialized and <em>n > 0</em>.
1256: @post The object's internal random number generator has been
1257: called once.
1258: */
1261: int getNextInt
1262: (
1263: int n //in
1264: );
1265: /**<
1266: Same as getNext(int n) above, but with a more explicit name,
1267: for readability rather than for ease of use when programming
1268: "generically".
1269: */
1272: int getNext
1273: (
1274: int low, //in
1275: int high //in
1276: );
1277: /**<
1278: Gets a pseudorandom integer in the range [low,high].
1279: @return A pseudorandom integer value in the range <em>[low,high]</em>.
1280: @param low A positive integer value <= the value of <em>high</em>.
1281: @param high A positive integer value >= the value of <em>low</em>.
1282: @pre <em>low</em> and <em>high</em> have been initialized, and
1283: <em>low <= high</em>.
1284: @post The object's internal random number generator has been called
1285: once.
1286: */
1289: int getNextInt
1290: (
1291: int low, //in
1292: int high //in
1293: );
1294: /**<
1295: Same as getNext(int low, int high) above, but with a more
1296: explicit name, for readability rather than for ease of use
1297: when programming "generically".
1298: */
1301: //
1302: //
1303: //********** Random double generators **********
1304: double getNext
1305: (
1306: double x //in
1307: );
1308: /**<
1309: Gets a pseudorandom real (double) in the range [0,x).
1310: @return A pseudorandom double value in the range <em>[0,x)</em>.
1311: @param x A positive real (double) number.
1312: @pre <em>x</em> has been initialized and <em>x > 0</em>.
1313: @post The object's internal random number generator has been called
1314: once.
1315: */
1318: double getNextDouble
1319: (
1320: double x //in
1321: );
1322: /**<
1323: Same as getNext(double x) above, but with a more explicit name,
1324: for readability rather than for ease of use when programming
1325: "generically".
1326: */
1329: double getNext
1330: (
1331: double low, //in
1332: double high //in
1333: );
1334: /**<
1335: Gets a pseudorandom real (double) value in the range [low,high).
1336: @return A pseudorandom real (double) value in the range
1337: <em>[low,high)</em>.
1338: @param low A positive real (double) value < the value of <em>high</em>.
1339: @param high A positive real (double) value > the value of <em>low</em>.
1340: @pre <em>low</em> and <em>high</em> have been initialized, and
1341: <em>low < high</em>.
1342: @post The object's internal random number generator has been called
1343: once.
1344: */
1347: double getNextDouble
1348: (
1349: double low, //in
1350: double high //in
1351: );
1352: /**<
1353: Same as getNext(double low, double high) above, but with a more
1354: explicit name, for readability rather than for ease of use
1355: when programming "generically".
1356: */
1359: //
1360: //
1361: //********** Random string generators **********
1362: string getNext
1363: (
1364: const string& s //in
1365: );
1366: /**<
1367: Gets a pseudorandom string based on the length and content of
1368: <em>s</em>.
1369: @return A pseudorandom string object.
1370: @param s Any string of characters.
1371: @pre <em>s</em> has been initialized and <em>s.length() >= 2</em>.
1372: Let <em>a</em> and <em>b</em> represent the first two distinct
1373: characters in <em>s</em>. Suppose <em>a</em> occurs in the first
1374: <em>low</em> contiguous locations in <em>s</em>. Suppose <em>b</em>
1375: occurs in the next <em>high</em> contiguous locations in <em>s</em>.
1376: It is required that <em>a < b</em> and that <em>low <= high</em>.
1377: @post
1378: A pseudorandom string object has been returned, according to these rules:
1379: -# If <em>low == high</em>, then the length of any returned
1380: string is their common value.
1381: -# If <em>low < high</em>, then the length of any returned value
1382: is a random value in the range [low,high].
1383: -# If <em>s.length() == low+high</em>, the characters in the
1384: returned value are in the char range [a,b].
1385: -# If <em>s.length() > low+high</em>, the characters in any
1386: returned value come from the set of all characters in s, excluding
1387: the first two distinct characters.
1388: */
1391: string getNextString
1392: (
1393: const string& s //in
1394: );
1395: /**<
1396: Same as getNext(const string& s) above, but with a more explicit
1397: name, for readability rather than for ease of use when programming
1398: "generically".
1399: */
1402: string getNext
1403: (
1404: const string& first, //in
1405: const string& second //in
1406: );
1407: /**<
1408: Gets a random string in the "range" between the two strings
1409: <em>first</em> and <em>second</em>.
1410: @return A pseudorandom string object.
1411: @param first The "lower bound" of a "string range" from which
1412: the pseudorandom string object will be chosen.
1413: @param second The "upper bound" of a "string range" from which
1414: the pseudorandom string object will be chosen.
1415: @pre
1416: -# <em>first</em> and <em>second</em> have been initialized.
1417: -# <em>first <= second</em>.
1418: -# <em>first.length() <= second.length()</em>.
1419: @post A pseudorandom string value <tt>r</tt> satisfying the
1420: following three conditions is returned:
1421: -# <em>first <= r <= second</em>.
1422: -# <em>first.length() <= r.length() <= second.length()</em>.
1423: -# <em>r</em> contains only characters found in either
1424: <em>first</em> or <em>second</em>.
1425: */
1428: string getNextString
1429: (
1430: const string& first, //in
1431: const string& second //in
1432: );
1433: /**<
1434: Same as getNext(const string& first, const string& second)
1435: above, but with a more explicit name, for readability rather than
1436: for ease of use when programming "generically".
1437: */
1440: //
1441: //
1442: //********** Auxiliary random string generators **********
1443: //These are public since they may also be useful to class clients.
1444: string getNextStringFromCharRange
1445: (
1446: int size, //in
1447: char firstChar, //in
1448: char lastChar //in
1449: );
1450: /**<
1451: Gets a pseudorandom string containing <em>size</em> characters
1452: from the character range <em>[firstChar,secondChar]</em>.
1453: @return A pseudorandom string object.
1454: @param size The size of the string to be returned.
1455: @param firstChar The lower bound of the character range from which the
1456: characters for the returned string will be taken.
1457: @param lastChar The upper bound of the character range from which the
1458: characters for the returned string will be taken.
1459: @pre <em>size</em>, <em>first</em> and <em>last</em> have been
1460: initialized, with <em>size >=1</em>, <em>first <= last</em>.
1461: @post A pseudorandom string value containing <em>size</em> printable
1462: characters in the range <em>[first,last]</em> has been returned.
1463: */
1465: string getNextStringFromString
1466: (
1467: int size, //in
1468: const string& source //in
1469: );
1470: /**<
1471: Gets a pseudorandom string containing <tt>size</tt> characters taken
1472: from the string <tt>s</tt>.
1473: @return A pseudorandom string object.
1474: @param size The size of the string to be returned.
1475: @param source The string from which the characters for the returned
1476: string will be taken.
1477: @pre <em>size</em> and <em>source</em> have been initialized, with
1478: <em>size >= 1</em> and <em>source</em> containing only printable
1479: characters.
1480: @post A random string value containing <em>size</em> printable
1481: characters, all of which appear in <em>source</em>, has been returned.
1482: */
1484: private:
1485: int seed;
1486: void my_srand(int& seed);
1487: int my_rand();
1488: };
1492: class Stopwatch
1493: /**
1494: For measuring the time taken by an algorithm to perform its task.
1495: An object of class <tt>%Stopwatch</tt> will behave like a stopwatch.
1496: It can be started, stopped, and asked for the time elapsed.
1497: This time can be computer time (clock ticks), or real time as measured
1498: in seconds, minutes, or hours.
1499: */
1500: {
1501: public:
1503: Stopwatch();
1504: /**<
1505: Default constructor.
1506: @pre None
1507: @post The clock time at the time of declaration has been recorded.
1508: */
1510: Stopwatch
1511: (
1512: const string nameOfEventToBeTimed //in
1513: );
1514: /**<
1515: Constructor which allows the naming of the event to be timed.
1516: @pre None
1517: @post The clock time at the time of declaration has been recorded,
1518: as well as the name of the event to be timed.
1519: */
1521: void setEventName
1522: (
1523: const string nameOfEventToBeTimed //in
1524: );
1525: /**<
1526: Sets, or resets, the name of the event to be timed.
1527: @return void
1528: @pre None
1529: @post The name of the event to be timed has been set to be the text
1530: contained in nameOfEventToBeTimed, which may be the empty string
1531: if no name is desired.
1532: */
1534: string getEventName() const;
1535: /**<
1536: Gets the current name of the event to be timed.
1537: @return The current name of the event to be timed.
1538: @pre None
1539: @post No side effects.
1540: */
1543: void start();
1544: /**<
1545: Causes the stopwatch to start running.
1546: @return void
1547: @pre <em>stop()</em> has been called, or <em>start()</em> has
1548: never been called.
1549: @post The stopwatch timer has been "started" and the clock time
1550: at start time has been recorded, in computer clock ticks.
1551: */
1554: void stop();
1555: /**<
1556: Causes the stopwatch to stop running.
1557: @return void
1558: @pre <em>start()</em> has been called.
1559: @post The stopwatch timer has been "stopped" and the accumulated
1560: time since <em>start()</em> was called has been recorded.
1561: */
1564: void delay
1565: (
1566: int delayFactor = 1 //in
1567: ) const;
1568: /**<
1569: Adds some multiple of an artifical amount of time to the
1570: accumulated time on the stopwatch.
1571: @return void
1572: @pre <tt>start()</tt> has been called.
1573: @post An artificial amount of time has been added to the total
1574: computer process time as reported by the clock function. In other
1575: words, during this delay time the "stopwatch" continues to
1576: accumulate time but nothing else happens. Thus this is a way to
1577: make an operation appear to take longer than it actually does.
1578: It can be used to cause the stopwatch to accumulate "artificial"
1579: time when monitoring the performance of an algorithm on a relatively
1580: small data set. This helps us to overcome the problem of trying to
1581: measure the amount of time taken to perform a calulation and finding
1582: that it took "no time at all". Note that we still cannot measure the
1583: absoute time taken, but fortunately we are often only interested in
1584: measuring the relative time taken by the same algorithm on data sets
1585: of different sizes, or by different algorithms on data sets of the
1586: same size. The input parameter <em>delayFactor</em> is a linear
1587: multiplier for increasing the amount of delay time. For example,
1588: a <em>delayFactor</em> of 2 doubles the amount of delay time
1589: accumulated by a single call to the <em>delay()</em> member function.
1590: */
1593: clock_t getTicks() const;
1594: /**<
1595: Gets the number of clock ticks between the most recent calls of
1596: <em>start()</em> and <em>stop()</em>.
1597: @return The number of clock ticks between the last calls to
1598: <em>start()</em> and <em>stop()</em>.
1599: @pre <em>start()</em> and <em>stop()</em> have been called (in that
1600: order).
1601: @post The accumulated time, in computer clock ticks, between the times
1602: when the stopwatch was last started and stopped, has been returned.
1603: */
1606: double getSeconds() const;
1607: /**<
1608: Gets the number of seconds between the last calls of
1609: <em>start()</em> and <em>stop()</em>.
1610: @return The number of seconds between the last calls to
1611: <em>start()</em> and <em>stop()</em>.
1612: @pre <em>start()</em> and <em>stop()</em> have been called
1613: (in that order).
1614: @post The accumulated time, in seconds, between the times when the
1615: stopwatch was last started and stopped, has been returned.
1616: */
1619: double getMinutes() const;
1620: /**<
1621: Gets the number of minutes between the last calls of
1622: <em>start()</em> and <em>stop()</em>.
1623: @return The number of minutes between the last calls to
1624: <em>start()</em> and <em>stop()</em>.
1625: @pre <em>start()</em> and <em>stop()</em> have been called (in
1626: that order).
1627: @post The accumulated time, in minutes, between the times when the
1628: stopwatch was last started and stopped, has been returned.
1629: */
1632: double getHours() const;
1633: /**<
1634: Gets the number of hours between the last calls of
1635: <em>start()</em> and <em>stop()</em>.
1636: @return The number of hours between the last calls to
1637: <em>start()</em> and <em>stop()</em>.
1638: @pre <em>start()</em> and <em>stop()</em> have been called
1639: (in that order).
1640: @post The accumulated time, in hours, between the times when
1641: the stopwatch was last started and stopped, has been returned.
1642: */
1645: void display() const;
1646: /**<
1647: Displays the time, in hours (as an integer value), minutes (as an
1648: integer value), and seconds (as a double value), between the last
1649: time this <tt>%Stopwatch</tt> object was started and stopped.
1650: @pre <em>start()</em> and <em>stop()</em> must have been called,
1651: in that order.
1652: @post
1653: - Case 1: If no name has been given to the event that has just been
1654: timed, the ouput displayed is this:
1655: <pre>
1656: Total time elapsed = hh:mm:ss.sss
1657: </pre>
1658: - Case 2: If a name (name-of-event) has been given to the event that
1659: has just been timed, the ouput displayed is this:
1660: <pre>
1661: Total time elapsed for event name-of-event = hh:mm:ss.sss
1662: </pre>
1663: */
1665: private:
1666: clock_t numClockTicksPassed;
1667: string eventName;
1668: };
1671: class TextItems
1672: /**
1673: For displaying on-line help and other text messages in
1674: console applications.
1675: The Textitems class provides a convenient mechanism for holding, in
1676: memory, any number of "text items" and displaying any one of these text
1677: items as required by the program. A "text item" consists of one or more
1678: lines of text and all text items are loaded in from a textfile, which
1679: must have the format specified below. One obvious use for this class
1680: would be for handling on-line help, but any text item, consisting of
1681: any number of lines, that needs to be displayed one or more times by
1682: a program may be considered a candiate to become a "text item".
1684: Any textfile containing text items must contain at least one text
1685: item. Any such file and each text item in it must be formatted
1686: according to the following rules:
1688: -# All lines of text from the beginning of the file down to the first
1689: line consisting of 40 equal signs will be ignored. Thus one or more
1690: lines that serve to identify file content to a human reader of the
1691: file may be placed before this line. Such a line of 40 equal signs
1692: must be left-justified. A left-justified line of 40 equal signs looks
1693: like this:
1694: <pre>
1695: ========================================
1696: </pre>
1697: -# The first line of each text item must be its "title", i.e., the
1698: exact string that will be used by the program to access that particular
1699: text item for display. The title is not displayed when the text item is
1700: displayed; it is used solely for identifying the item. There must be no
1701: leading or trailing spaces in the title.
1702: -# Each text item must be terminated by a line of exactly 40 dashes
1703: (hyphens) which is not regarded as part of the item itself (and is
1704: therefore not displayed when the text item is shown on the screen).
1705: Each item-terminating line of 40 dashes must be left-justified.
1706: A left-justified line of 40 dashes looks like this:
1707: <pre>
1708: ----------------------------------------
1709: </pre>
1710: -# The body of a text item may contain one or more lines consisting
1711: of exactly 40 exclamation marks (!) among the lines of "regular" text.
1712: Such a line indicates a point where the display must pause and ask the
1713: user to press Enter to continue, but the line itself is not displayed.
1714: Such a line of 40 exclamation marks must be left-justified. A
1715: left-justified line of 40 exclamation marks looks like this:
1716: <pre>
1717: !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1718: </pre>
1719: -# The last text item in the file must be followed immediately by an
1720: additional line of 40 equal signs like that shown above. Any text
1721: following this line in the file will also be ignored. It may thus
1722: be inferred that a file of text items will normally contain exactly
1723: two left-justified lines consisting of 40 equal signs, and there may
1724: (or may not) be text before the first one, and after the second one,
1725: with all such text being ingored by any program reading the file.
1726: -# Keep all lines in a text item strictly less than 80 characters in
1727: length. In the first place, any line longer than this will likely wrap
1728: to a second line, and may not break where you'd like it to. Second,
1729: some systems (DOS/Windows, for example) seem to put an automatic line
1730: feed at the end of each line of exactly 80 characters.
1731: So, keeping lines under 80 characters in length will avoid extraneous
1732: blank lines in the output that might be introduced in this way.
1733: */
1734: {
1735: public:
1737: TextItems();
1738: /**<
1739: Default constructor.
1740: @pre None
1741: @post The list of text items has been initialized and is empty.
1742: However, the program is then terminated after displaying the
1743: following 6-line message:
1744: <pre>
1745: Error: File name must be supplied when declaring
1746: a %TextItems object, as in (for example):
1747: %TextItems myTextItems("my_text_item_file.dat");
1748: Program is now terminating.
1749: Press Enter to continue ...
1750: </pre>
1751: */
1754: TextItems
1755: (
1756: const string fileName //in
1757: );
1758: /**<
1759: Constructor which gets its list of text items from a textfile.
1760: @pre <em>fileName</em> has been initialized.
1761: @post
1762: - Case 1 (typical): If <em>fileName</em> contains the name (or
1763: the full pathname) of a properly-formatted file of text items, all
1764: text items in that file have been read into memory and the constructed
1765: object contains this list of text items.
1766: - Case 2 (error): If <em>fileName</em> contains the name of
1767: an empty file, the program displays this 3-line message:
1768: <pre>
1769: Error: Input file of text items is empty.
1770: Program is now terminating.
1771: Press Enter to continue ...
1772: </pre>
1773: - Case 3: If <em>fileName</em> contains the name of a file that
1774: doesn't exist, the program will give the user one opportunity to
1775: rectify the situation by entering, from the standard input, the
1776: name of a valid file of text items (or the name and path to the
1777: file if it's not in the working directory). If the user then fails
1778: to do so, the program displays this 3-line message:
1779: <pre>
1780: Error: Input file of text items does not exist.
1781: Program is now terminating.
1782: Press Enter to continue ...
1783: </pre>
1784: The program thus terminates if a validly-named file is empty, or
1785: if the name of a valid file is not supplied, either initially, or
1786: during the one additional permitted attempt.
1787: */
1790: void displayItem
1791: (
1792: const string title //in
1793: ) const;
1794: /**<
1795: Displays a text item on the standard output.
1796: @pre <em>title</em> has been initialized.
1797: @post
1798: - Case 1 (typical): The text item identified by <em>title</em>
1799: has been displayed.
1800: - Case 2 (error): If the text item designated by <em>title</em>
1801: cannot be found, the following 2-line message is displayed:
1802: <pre>
1803: Error: Text item \<\<title\>\> not found.
1804: Press Enter to continue ...
1805: </pre>
1806: */
1808: private:
1809: vector< vector<string> > itemList;
1810: };
1813: //DisplayOpeningScreen free function
1814: //********************************************************************
1815: inline void DisplayOpeningScreen
1816: (
1817: const string& programmerInfo, //in
1818: const string& programInfo, //in
1819: int numBlankLinesBefore, //in
1820: int numBlankLinesAfter //in
1821: )
1822: {
1823: string blankLinesBefore(numBlankLinesBefore, '\n'),
1824: blankLinesAfter(numBlankLinesAfter, '\n');
1825: cout << blankLinesBefore
1826: << programmerInfo << "\n"
1827: << programInfo
1828: << "\nThe main driver of this executable was built on " << __DATE__
1829: << " at " << __TIME__ << ".\n"
1830: << blankLinesAfter;
1831: Pause();
1832: }
1834: } //End of this part of namespace Scobey
1836: #endif