-
Often part of the program that has to deal with the raw input quickly becomes
one of the most problematic components of the entire application. The code can
be tough to understand and maintain. Your next effort will be to
enhance the input functionality of your program to diversify
acceptable date styles. To do that, you should switch to reading unformatted
character sequence, similar to the input loop in lecture sample
program strstream.cpp (download
source code here.)
-
Consider
7/4/1776
07/04/1776
Jul 4 1776
JUL, 4 1776
jul 4, 1776
Each date looks fine to the user, but presents a new challenge to the
programmer. How can this mix be successfully translated to the proper int
Month, int Day, and int Year ?
-
In strstream.cpp , each individual character is
obtained via call to std::cin.get( ).
The program invokes ANSI C character classification functions, such as isalpha(
) and isdigit( ) to make
decisions about the input. Once the decision is made, the program generates its
own stream of data accumulated by the string stream object named str_stream
.
-
Think about the possibilities of input formats: the first character could be
either a digit or a letter corresponding to the name of the month; the second
character could either be a digit or a letter, and so on. Commas, spaces and
slashes are legal input delimiters.
-
Keep record of the input position of each character in a separate variable.
-
The month is the nastiest part: it is either a three-letter abbreviation, or a
one- or two-digit decimal number. In either case, under no circumstance the
length of the month can be longer than 3 characters. Because of this, you
should store first three characters of the raw input in a separate set of
variables, e.g.
char month_abbrev_1st;
char month_abbrev_2nd;
char month_abbrev_3rd;
Later you can decide how to interpret month by looking at the value of month_abbrev_1st
variable.
-
Your program could have three different std::stringstream objects
to accumulate data about what you think should belong to the month part, the
day part, and the year, respectively.
-
Once input is broken into pieces corresponding to month, date, and year, you
can convert them to integers. Recall function string2type( )
from another lecture sample, manipulators.cpp
(download). You can use string2type(
) to convert all "numeric" inputs.
-
If first input character is not a digit, you will have to inspect month's name
and choose the month manually. I've noticed that in the ASCII world the sum of
second and third lowercase characters of each month name is unique. Therefore,
one could try
switch( tolower( second_ ) + tolower( third_ ) )
{
case 'a' + 'n': return 1; // Jan
case 'e' + 'b': return 2; // Feb
case 'a' + 'r': return 3; // Mar
case 'p' + 'r': return 4; // Apr
case 'a' + 'y': return 5; // May
case 'u' + 'n': return 6; // Jun
case 'u' + 'l': return 7; // Jul
case 'u' + 'g': return 8; // Aug
case 'e' + 'p': return 9; // Sep
case 'c' + 't': return 10; // Oct
case 'o' + 'v': return 11; // Nov
case 'e' + 'c': return 12; // Dec
default: return 0; // bad month...
}
-
You don't have to make everything perfect, but try your best and see how much
progress you can make with the raw input.
|