This lab will help you show your mastery of strings (and branching, looping, etc.).
Write a program that reads in a sentence from the user. But wait! That's not all it must do! Your program should output the sentence with spacing corrected and with letters corrected for capitalization.
In terms of spacing correctness, the output sentence should have all sequences of two or more blanks compressed to a single space — unless there were blanks at the beginning of the sentence. Blanks at the beginning of a sentence should be obliterated utterly! (Blank here can mean any type of spacing — space, tab, new-line, ...)
The sentence should start with an uppercase letter but should contain no other uppercase letters. (Do not worry about proper names; if their first letters are changed to lowercase, that's acceptable.)
For simplicity, you may assume that the user's sentence ends in a period and contains no other periods (i.e. no abbreviations or such).
$ sentence.out
Welcome to the Style Stabilizing Program!
Please enter your sentence (end with a period):
the Answer to life, the Universe, and everything
IS 42.
Corrected, your sentence is:
The answer to life, the universe, and everything is 42.
Thanks for stabilizing your style with us today!
Try to have a punctual day here-after!
$
Perhaps, you might find this example of help..?
How can you read in an entire line of text at once? Does this act — even sometimes — need any special precaution?
How do you let the line of text end with something other than a \n? (Hint: Maybe it could involve a default argument or an overloaded version of the function you found above...)
Once you've read in an entire 'line' of text, how can you clean up the spacing (in case the user has a sticky space-bar or tab key, for instance)? (Hint: You aren't actually erase'ing the extra spaces per-se, but rather replace'ing lots (i.e. all pairs) of spaces with a little space (i.e. a single space). Seriously! See the referenced example!)
This assignment is (Level 2).
Add (Level 1) to wrap their resulting line at a length they can set (it should default to 70 characters).
Heck, I'll throw in another (Level 2) if you wrap their line such that words aren't split in two. For instance, Wrapping the above example to a length of 10 would be:
The answer to life, t he univers e, and eve rything is 42.
(Note how spacing at the boundary doesn't carry since we begin a new line.)
But wrapping it to 10 without breaking a word would look like:
The answer to life, the universe, and everything is 42.
The big, hairy question of the day is: What if an individual word is longer than the line length they chose?
For instance, if the example sentence were wrapped without breaking words to a line length of 7, we'd have trouble with both 'universe,' and 'everything' since they are both longer than 7 characters.
We could just presume to break it — since the user is an idiot, anyway:
The answer to life, the univers e, and everyth ing is 42.
Finally, add another (Level 2) to hyphenate when you break a word. This can be done with or without the 'try-not-to-break-a-word' option.
For example, the 10-line-length 'words-can-break' example would become:
The answer to life, the unive- rse, and everythin- g is 42.
Note how 'the' didn't break now since to insert the - would have left nothing of the word on the line... The same happened with 'everything' — only the 'e' was there (after the 'the' shifted things) and so inserting a - would have left nothing.
With the 'try-not-to-break-a-word' (line-length 7 example) it would be:
The answer to life, the univer- se, and everyt- hing is 42.
How can you output a \n every nth character as you print the string contents? (Hint: The position of the 5th, 10th, 15th, etc. characters are 4, 9, 14, etc. What is the relationship between these positions and 5?) (Hint to the Hint: Think 'shift' or 'translate' (like a graph in algebra ...or a set of values we've randomly generated) and 'divide'...er...well, not exactly 'divide'...but...um...like 'divide'...)
If you've reached position i where a new-line is to be printed, how do you detect that you are in the middle of a word? If you are, how do you back up to the beginning of that word? (Note: You can't just print along and insert new-lines with the word-wrapping version you'll kind-of have to decide what to print before you begin printing. Perhaps you should think of it more as: "Does the next word get printed or will my line end inside of it?")
When hyphenating, how do you know that inserting a hyphen is going to leave nothing of a word on the line? (Hint: This is related to the last question...)
Add (Level 2) to fully justify their resulting line to the set-table length (mentioned in the previous option). This should insert spaces evenly through the string to make it the specified length long. (Don't simply add the necessary spaces all at one location — it should look as natural as possible.) Also note that, if combined with the option above, the last (wrapped) line should not be justified (like the last line of a paragraph).
How do you prepare a line of text that will be printed, but isn't being printed right now — only after more processing?
How can you tell how many spaces are missing from a line of text you are 'about to' print?
How do you find places where there currently is spacing to add the 'missing' spaces?
How do you spread the 'missing' spaces as evenly as possible through the line? (Hint: Think of odd spacing as a 'middle' thing and even spacing as an 'ends' thing. This will help balance the teeter-totter of your spacing.)
Add (Level 1) to allow the user to tell you what the terminating character is (of course, we assumed above that the user was done at the first . they'd input). If the user can set this to anything they want, they can enter more text — several sentences, even.
Add (Level 1.5) to place all of these options (all the ones you implement, anyway) into a menu structure. Perhaps something like:
1) set wrap Length 2) set Justification (left) 3) set Termination character 4) Enter text 5) Print processed text 6) Quit
(Don't forget the asynchronous nature of a menu! I.E. the user may choose to print before there has been any text entered — so protect yourself from this eventuality or make sure your processing routines behave well when presented with an empty string. Or, perhaps more tricky, the user may enter text and print with default option settings for processing. Then, without entering new text, they can change the option setting(s) and request a new printing!
Note that this means you can not (completely) process the text as it comes in — you must perform the option-based processing of the text just before or as you print it. ...just before would be best, btw.)
The justification option might lead to a submenu like:
Justification: 1) Left (*) 2) Right 3) Full 4) Center 5) neVermind
(The nevermind option simply returns to the Main Menu without altering the justification.) The * denotes the current setting (just as the word did in the Main Menu). BTW, to actually implement all the justifications is worth another (Level 1) (left is no extra, right and center are about 0.5 each).
Add (Level 1.5) to place all of your string prettifying functions into a library for easy re-use.