Aleks
Aleks

Reputation: 91

C program Sorting Dates

I am doing a C program to sort the dates the user has entered chronologically using the built-in qsort function. I am using structs. My code however does not sort them properly. Any help? Here is the bit of code that I call in my qsort.

int comparator(const void *p, const void *q) 
{
    int l3 = ((struct dates *)p)->year;
    int r3 = ((struct dates *)q)->year; 

    if(l3 >= 90 || l3<=99 ){
        if(l3 > r3){
            return 1;   
        }
        else if(l3 < r3){
            return -1;
        }
    }
    else if(l3 > 99){         
        if(l3 > r3){
            return 1;   
        }
        else if(l3 < r3){
            return -1;
        }            
    }   

    int l2 = stringtoInt(((struct dates *)p)->month);
    int r2 = stringtoInt(((struct dates *)q)->month); 

    if (l2 > r2)
    {
        return 1;
    }
    else if ( l2 < r2)
    {
        return -1;
    }

    int l = ((struct dates *)p)->day;
    int r = ((struct dates *)q)->day; 

    if (l > r)
    {
        return 1;
    }
    else if ( l < r)
    {
        return -1;
    }          
}

Upvotes: 0

Views: 2415

Answers (3)

Rahul Kushwaha
Rahul Kushwaha

Reputation: 13

I was working on a schedule maker program so here's the code i have used to sort dates

void LinkedList::appendNode(Node* newNode){
    Node *ptr = head;
    if (head == NULL){
        head = newNode;
    }else{
        //First compare years if newNode year is less than 1st node if yes, interchange them
        if(ptr->year > newNode->year){
            newNode->link = head;
            head = newNode;
        }
        //if years are same then compare months
        else if(ptr->year == newNode->year){

            //compare if newNode month is less than the 1st node in list if yes, interchange them
            if(ptr->month > newNode->month){
                newNode->link = head;
                head = newNode;
            }
            //if months of both are equal compare dates
            else if(ptr->month == newNode->month){

                //compare if date of newNode is smaller than the 1st node. If yes, interchange them
                if(ptr->date > newNode->date){
                    newNode->link = head;
                    head = newNode;
                }
                //if dates are same then, check time
                else if(ptr->date == newNode->date){

                    //compare the hour
                    if(ptr->hour > newNode->hour){
                        newNode->link = head;
                        head = newNode;
                    }
                    //if hour is same check time
                    else if(ptr->hour == newNode->hour){

                        //compare the minute
                        if(ptr->min > newNode->min){
                            newNode->link = head;
                            head = newNode;
                        }
                        else if(ptr->min == newNode->min){
                            newNode->link = head;
                            head = newNode;
                        }
                        //if minute in newNode is greater then traverse and place it accordingly
                        else{
                            ptr = head;

                            //traverse the link till the next node is greater than the newNode
                            while(ptr->link != NULL){
                                if(ptr->link->year > newNode->year)
                                    break;
                                else if(ptr->link->year == newNode->year && ptr->link->month > newNode->month)
                                    break;
                                else if(ptr->link->year == newNode->year && ptr->link->month > newNode->month && ptr->link->date > newNode->date)
                                    break;
                                else if(ptr->link->year==newNode->year&&ptr->link->month>newNode->month&&ptr->link->date==newNode->date&&ptr->link->hour>newNode->hour)
                                    break;
                                else if(ptr->link->year==newNode->year&&ptr->link->month>newNode->month&&ptr->link->date==newNode->date&&ptr->link->hour==newNode->hour&&ptr->link->min>newNode->min)
                                    break;
                                ptr = ptr->link;
                            }
                            newNode->link = ptr->link;
                            ptr->link = newNode;
                        }
                    }

                    //if hour in newNode is greater then traverse and place it accordingly
                    else{
                        ptr = head;
                        //traverse the link till the next node is greater than the newNode
                        while(ptr->link != NULL){
                            if(ptr->link->year > newNode->year)
                                break;
                            else if(ptr->link->year == newNode->year && ptr->link->month > newNode->month)
                                break;
                            else if(ptr->link->year == newNode->year && ptr->link->month > newNode->month && ptr->link->date > newNode->date)
                                break;
                            else if(ptr->link->year==newNode->year&&ptr->link->month>newNode->month&&ptr->link->date==newNode->date&&ptr->link->hour>newNode->hour)
                                break;
                            else if(ptr->link->year==newNode->year&&ptr->link->month>newNode->month&&ptr->link->date==newNode->date&&ptr->link->hour==newNode->hour&&ptr->link->min>newNode->min)
                                break;
                            ptr = ptr->link;
                        }
                        newNode->link = ptr->link;
                        ptr->link = newNode;
                    }
                }
                //else if newNode date is greater
                else{
                    ptr = head;
                    //traverse the link till the next node is greater than the newNode
                    while(ptr->link != NULL){
                        if(ptr->link->year > newNode->year)
                            break;
                        else if(ptr->link->year == newNode->year && ptr->link->month > newNode->month)
                            break;
                        else if(ptr->link->year == newNode->year && ptr->link->month > newNode->month && ptr->link->date > newNode->date)
                            break;
                        ptr = ptr->link;
                    }
                    newNode->link = ptr->link;
                    ptr->link = newNode;
                }
            }
            //else if the month of newNode is greater
            else{
                ptr = head;
                //traverse the link till the next node is greater than the newNode
                while(ptr->link != NULL){
                    if(ptr->link->year > newNode->year)
                        break;
                    else if(ptr->link->year == newNode->year && ptr->link->month > newNode->month)
                        break;
                    else if(ptr->link->year == newNode->year && ptr->link->month > newNode->month && ptr->link->date > newNode->date)
                        break;
                    ptr = ptr->link;
                }
                newNode->link = ptr->link;
                ptr->link = newNode;
            }
        }
        //else if the year of year of newNode is greater
        else{
            ptr = head;
            //traverse the link till the next node is greater than the newNode
            while(ptr->link != NULL){
                if(ptr->link->year > newNode->year)
                    break;
                else if(ptr->link->year == newNode->year && ptr->link->month > newNode->month)
                    break;
                else if(ptr->link->year == newNode->year && ptr->link->month > newNode->month && ptr->link->date > newNode->date)
                    break;
                ptr = ptr->link;
            }
            newNode->link = ptr->link;
            ptr->link = newNode;
        }
    }
}

Upvotes: 0

user3629249
user3629249

Reputation: 16540

The posted code seems to be assuming that the year fields are only 2 digits. It that a valid assumption?

this line:

else if(l3 > 99){

is not correct, because a 2 digit year 'should' never by greater than 99.

(I would suggest using 4 digit years, but such is your data design choice)

However, it seems that if the year is not in the range 90...99 inclusive, then it has to be in the new century

so no need to be checking if the year is > 99, just assume it is in the new century.

What happens when the one-date is in the prior century (90...99) and the other-date is in the next century? The code does not seem to be accounting for that condition.

Upvotes: 0

Ben Frankel
Ben Frankel

Reputation: 174

Your first if construct,

if (l3 >= 90 || l3 <= 99)

will always evaluate to true, so the following else if will never be entered. I'm assuming the condition is meant to be l3 >= 90 && l3 <= 99, although if that's the case, since the following else if has the same body, you could merge them into a single if statement, if (l3 >= 90).

Furthermore, you aren't handling the case where l3 < 90, so in that case your comparator will ignore year and move on to comparing by month and then day.

I would also add an explicit return 0 at the end of the function, when the dates are determined to be equal.

Upvotes: 3

Related Questions