user14551695
user14551695

Reputation:

Function strtoul doesn't read full string

I'm creating a program that inputs the date as XX/XX/XXXX and outputs it as Month, Day, Year. I'm inputting the date as a string, and getting a number out of it using strtoul. The function stops reading and returns a value after a non-number character is found, but when I don't includes any slashes, the program works.

// inputs date as string in format "XX/XX/XXXX"
// and outputs date in format "MONTH XX, XXXX"
#include <stdio.h>
#include <stdlib.h>
#define SIZE 11

void displayDate(unsigned long int dateNum);

int main(void)
{
    char dateString[SIZE]; // initialize input string
    
    printf("%s", "Input a date in format XX/XX/XXXX: ");
    fgets(dateString, SIZE, stdin); // get date string
    
    char *datePtr; // char pointer
    
    unsigned long int dateNum = strtoul(dateString, &datePtr, 0);
    
    printf("%lu", dateNum);
        
    // call function to display date
    // in different format
    displayDate(dateNum); 
}   

void displayDate(unsigned long int dateNum)
{
    unsigned long int month = dateNum / 1000000; // calculate month
    
    unsigned long int day = (dateNum % 1000000) / 10000; // calculate day
    
    unsigned long int year = dateNum % 10000; // calculate year
    
    // ensure valid date
    // otherwise display "Invalid date."
    if (month > 0 && month < 13 && day > 0 && day < 32) {
        // switch prints month
        switch (month) {
            case 1:
                printf("%s", "January");
                break;
            case 2:
                printf("%s", "February");
                break;
            case 3:
                printf("%s", "March");
                break;
            case 4:
                printf("%s", "April");
                break;
            case 5:
                printf("%s", "May");
                break;
            case 6:
                printf("%s", "June");
                break;
            case 7:
                printf("%s", "July");
                break;
            case 8:
                printf("%s", "August");
                break;
            case 9:
                printf("%s", "September");
                break;
            case 10:
                printf("%s", "October");
                break;
            case 11:
                printf("%s", "November");
                break;
            case 12:
                printf("%s", "December");
                break;
        }
        
        // printf statement prints remainder of date
        printf(" %lu, %lu\n", day, year);
    }
    else {
        puts("Invalid date.");
    }
}

Upvotes: 0

Views: 72

Answers (2)

user14551695
user14551695

Reputation:

I forgot to post this, but I just called the function three times to get the month, day, and year respectively, incrementing datePtr between each call.

Upvotes: 0

William Pursell
William Pursell

Reputation: 212356

You could simply do something like:

#include<stdio.h>
#include<stdlib.h>
#include<err.h>

int
main(int argc, char **argv)
{
        unsigned long month, day, year;
        char *months[] = { "Jan", "Feb", "Mar", "Apr", "May", "June",
                "July", "August", "Sept", "Oct", "Nov", "Dec" };
        char *k;
        if( argc < 2 ){
                errx(1, "missing date.  Enter in form mm/dd/yyyy");
        }
        month = strtoul(argv[1], &k, 10);
        if( *k != '/' ){
                errx(1, "Invalid format");
        }
        day = strtoul(k + 1, &k, 10);
        if( *k != '/' ){
                errx(1, "Invalid format");
        }
        year = strtoul(k + 1, &k, 10);
        if( *k != '\0' ){
                errx(1, "Invalid format");
        }
        if( month > 0 && month < 13 ){
                printf("%s %lu, %lu\n", months[month - 1], day, year);
        } else {
                errx(1, "Invalid date");
        }
        return EXIT_SUCCESS;
}

Upvotes: 1

Related Questions