Ankit
Ankit

Reputation: 51

Enter date data type from user

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

Answers (3)

DeftlyHacked
DeftlyHacked

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:

  • A day (01 to 31)
  • A month (01 to 12 or 'January' to 'December")
  • A year (70-99 and 00-16 or 1970 to 2016)

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

Gopi
Gopi

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

Sourav Ghosh
Sourav Ghosh

Reputation: 134286

Well, the easiest [and probably the safest] way to achieve this is to

  1. take the input as string using fgets()
  2. tokenize the string tusing strtok_r(), using the ., -, / as delimiter, and probably the strlen() to differenciate between dd, mm and yyyy.
  3. convert the strings to inegers using strtol() ans store accordingly.

Needless to mention, don't forget to validate the data afterwards.

Upvotes: 1

Related Questions