Reputation: 51
I am faced with a problem that i want user to enter the date .The date entered by user can be of any format eg. dd-mm-yy
, dd-mm-yyyy
,dd-month-yy
. I can think of only 2 ways to do it.
1.Using structures. But the date format is not specified.
2.Using sscanf()
and sprintf()
function to copy as string and then obtaining invidual values using sscanf() function.
Please correct me.
Upvotes: 3
Views: 554
Reputation: 405
I'm gonna be the devils advocate here and recommend writing a simple parser.
Let's look at the formats and see what we're going to be accepting:
Below is something I just slapped together as an example
#include <ctype.h> // isalpha, isdigit
#include <string.h> // strncmp
struct DATE {
int day, month, year;
};
// return 1 on success, else 0 on failure
int readdate(DATE *date, char *text) {
int toklen = 0;
char *tokval;
if (isdigit(*text)) { // expect a number for the day
date->day = *text++ - '0';
if (isdigit(*text)) // accept another number
date->day = date->day * 10 + *text++ - '0';
if (date->day < 1 || date->day > 31)
return 0;
} else return 0;
if (*text == '-') // expect a hyphen
text++;
else
return 0;
if (isdigit(*text)) { // accept a number for the month...
date->month = *text++ - '0';
if (isdigit(*text)) // accept another number
date->month = date->month * 10 + *text++ - '0';
if (date->month == 0 || date->month > 12)
return 0;
} else if (isalpha(*text)) {
tokval = text; // accept a word
do {
toklen++;
text++:
} while (isalpha(*text));
/* expect that the word is a name of a month */
if (!strncmp("january", tokval, toklen))
date->month = 1;
else if (!strncmp("february", tokval, toklen))
date->month = 2;
else if (!strncmp("march", tokval, toklen))
date->month = 3;
else if (!strncmp("april", tokval, toklen))
date->month = 4;
else if (!strncmp("may", tokval, toklen))
date->month = 5;
else if (!strncmp("june", tokval, toklen))
date->month = 6;
else if (!strncmp("july", tokval, toklen))
date->month = 7;
else if (!strcmp("august", tokval, toklen))
date->month = 8;
else if (!strcmp("september", tokval, toklen))
date->month = 9;
else if (!strcmp("october", tokval, toklen))
date->month = 10;
else if (!strcmp("november", tokval, toklen))
date->month = 11;
else if (!strcmp("december", tokval, toklen))
date->month = 12;
else
return 0;
} else return 0;
if (*text == '-') // expect a hyphen
text++;
else
return 0;
if (isdigit(*text)) { // expect a number
date->year = *text++ - '0';
if (isdigit(*text)) { // expect another number
date->year = date->year * 10 + *text++ - '0';
if (isdigit(*text)) { // accept another number
date->year = date->year * 10 + *text++ - '0';
if (isdigit(*text)) // expect another number
date->year = date->year * 10 + *text++ - '0';
else
return 0;
}
} else return 0;
/* ensure the year fits a valid range */
if (date->year >= 70 && date->year <= 99)
date->year += 1900;
else if (date->year < 70)
date->year += 2000;
if (date->year < 1970 || date->year > 2070)
return 0;
} else return 0;
/*
* you can do some optional checking on the date here to verify if the
* day of the month is valid here
*/
return 1;
}
When you start getting into dealing with multiple string formats, it's often easier and more manageable in the long run to just write a simple parser. But that's just my 2 cents.
Upvotes: 0
Reputation: 19864
Use strtok() as shown below and you can get the entered date in any of the formats mentioned in your question.
int main()
{
char *p;
char a[20];
printf("ENter date:\n");
scanf("%s",a);
p = strtok(a,"-");
while( p != NULL)
{
printf("%s ",p);/* I am printing here you can do what even you want to */
p = strtok(NULL,"-");
}
}
Upvotes: 0
Reputation: 134286
Well, the easiest [and probably the safest] way to achieve this is to
fgets()
strtok_r()
, using the .
, -
, /
as delimiter, and probably the strlen()
to differenciate between dd
, mm
and yyyy
. strtol()
ans store accordingly.Needless to mention, don't forget to validate the data afterwards.
Upvotes: 1