How would you go about creating an exact age calculator

Pages: 1234
! means "not"... as in, if the condition provided is false, it becomes true... and if it's true it becomes false (basically it inverts it)

|| means "or", which means if either of the 2 conditions are true, then the overall result is true.

&& means "and", which means that both of the 2 conditions must be true... otherwise the overall result is false.


if() conditions perform their {block contents} if the condition results in true.

So.... giblit's pseudo-code example:

if((leapyear && day > 29 && February) || (!leapyear && day > 28 && February))

in English:

if it's a leap year, AND the day is > 29, AND the month is February
OR
if it's NOT a leap year, AND the day is > 28, AND the month is February

then do the {block contents}
Thank you, so much helped me out a lot
This does not do what you think. And in fact, I don't even know what you're trying to do here. General rule of thumb is: don't use the comma operator. The comma operator does not do what you think it does.

I'm starting to believe that there must be some textbook or web page out there, that tells C++ novices that the comma is a magical symbol that allows the compiler to read the programmer's mind, and replace the comma with whatever it was the programmer really wanted to do.

I mean, typing in a random punctuation mark when you don't know what it means, is such a weird, illogical thing to do. And yet, over and over again, we see people here doing it.

There must be some reason for it.
I think it's related to the world we live in for example. When are you going to work? Monday, Tuesday, Thursday, Wednesday, Sunday.
When are you going to work? Monday, Tuesday, Thursday, Wednesday, Sunday.
Ugh I would either say "Monday, Tuesday, Wednesday, Thursday, and Sunday" or "Monday through Thursday and Sunday." I wouldn't have them in some arbitrary order.

Though that is different than something like for example yours cYear > 2014,2015,2017,2018,2019,2021,2022,2023,2025,2026,2027,2029,2030 What we don't understand is what that is supposed to mean?

If it is supposed to be greater than all of them why not just do cYear > 2030 because the only way to be greater than a range of values would be to be greater than the largest.

If it is an or then you would have to see if cYear > 2014 again the only way to be greater than any of them would be to be greater than the smallest. So the statement is pretty confusing on what you were trying to do.
Last edited on
Alright so the if((leapyear && day > 29 && February) || (!leapyear && day > 28 && February)) is good, but how could i possibly create a variable which has leap years in it?
bool leapyear = checkLeapYear(year);

1
2
3
4
bool checkLeapYear(unsigned const year)
{
    return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
}
as far as the februrary thing..you can figure that out I think but if not month == 2
Last edited on
you could also do something like this for the days :

1
2
3
4
5
6
7
8
int days = 0;
if(cMonth == 1)
{
    days = 31 - cDay;
}
cout << "you are ";
cout << days;
cout << " days old";

and just do that x12 times and of course look up how many days there are in each month and add them up for every month, that's the easy way i did mine and i know about leap years but cba. hehe
Last edited on
Since this is nearly 3 weeks old... I'm going to assume OP has finished this by now. I got bored and whipped up a solution I felt like posting.

I forgot how much I hated dealing with text input. Like 90% of this code is freaking input validation.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178

#include <iostream>
#include <string>
#include <sstream>

struct Date
{
    int year;
    int month;
    int day;
};


// convenience operator to see if one date is before/after another
bool operator >= (const Date& l, const Date& r)
{
    if(l.year > r.year)     return true;
    if(l.year < r.year)     return false;
    if(l.month > r.month)   return true;
    if(l.month < r.month)   return false;
    return (l.day >= r.day);
}

bool isLeapYear(int year)
{
    if(year < 0)        return false;   // <- can't have negative months wtf

    // years not divisible by 4 are never leap years
    if(year % 4)        return false;

    // years divisible by 400 are always leap years
    if(!(year % 400))   return true;

    // other years divisible by 100 are never leap years
    if(!(year % 100))   return false;

    // if we made it here, this is a leap year
    return true;
}

int daysInMonth(int month, int year)
{
    if(month >= 12)     return 0;       // 0 days in non-existent months

    // February is stupid
    if(month == 1)
    {
        if(isLeapYear(year))
            return 29;
        else
            return 28;
    }

    // all other months can be a lut
    static const int lut[12] = {31,0,31,30,31,30,31,31,30,31,30,31};
    return lut[month];
}

int daysInPreviousMonth(int month, int year)
{
    if(month == 0)
        return daysInMonth(11,year-1);
    else
        return daysInMonth(month-1,year);
}

bool parseDate(const std::string& str, Date& date)
{
    std::stringstream s(str);

    // date is in the form mm/dd/yyyy

    // I hate parsing text.  I kind of suck at it too.  This will work but is pretty ugly:
    if(!(s >> date.month))      return false;
    if(s.get() != '/')          return false;
    if(!(s >> date.day))        return false;
    if(s.get() != '/')          return false;
    if(!(s >> date.year))       return false;

    // offset days and months by 1  (we want January to be 0, not 1.  1-based is stupid)
    date.month -= 1;
    date.day -= 1;

    // months must be between 0-11
    if(date.month < 0)          return false;
    if(date.month >= 12)        return false;
    
    // and let's say the year must be > 1, just to prevent some wrapping errors
    if(date.year <= 1)          return false;

    // days must be less than the number of days in this month
    if(date.day >= daysInMonth(date.month,date.year))   return false;
    if(date.day < 0)                                    return false;

    // if all that checks out, we have a valid date
    return true;
}

bool getDateFromUser(const char* message, Date& date)
{
    std::string str;

    // print our message to the user
    std::cout << message;

    // loop until we get valid input
    while(true)
    {
        std::getline(std::cin,str);
        if(str.empty())         return false;       // user wants to exit

        if(parseDate(str,date)) return true;        // user gave us valid input

        // otherwise, invalid input.  Keep looping
        std::cout << "Invalid input.\n" << message;
    }
}

Date calcDifference(const Date& birth, const Date& current)
{
    Date result;
    
    result.day =    current.day - birth.day;
    result.month =  current.month - birth.month;
    result.year =   current.year - birth.year;

    // if we have negative days, borrow from the previous month
    if(result.day < 0)
    {
        result.month -= 1;
        result.day += daysInPreviousMonth(current.month,current.year);
    }

    // if we have negative months, borrow from the previous year
    if(result.month < 0)
    {
        result.year -= 1;
        result.month += 12;
    }

    return result;
}

// a stupid little function to give a 's' suffix for numbers other than 1
const char* suffix(int num)
{
    if(num == 1)        return "";
    else                return "s";
}

int main()
{
    Date birth, current, age;

    std::cout << "Age calculator.  Input an empty line to quit.\n\n";

    // loop until user wants to quit
    while(true)
    {
        // get the birth date
        if(!getDateFromUser("Input your birth date  (mm/dd/yyyy):  ",birth))     return 0;   // return (quit) if they input nothing
        if(!getDateFromUser("Input the current date (mm/dd/yyyy):  ",current))   return 0;   // return (quit) if they input nothing

        // make sure the current date is after the birth date
        if(current >= birth)
        {
            age = calcDifference(birth,current);
            std::cout << "\nYou are "
                      << age.year << " year" << suffix(age.year) << ", "
                      << age.month << " month" << suffix(age.month) << ", and "
                      << age.day << " day" << suffix(age.day) << " old.\n\n";
        }
        else
        {
            std::cout << "Your birth date must be after the current date.  Please try again.\n\n";
        }
    }
}
I am not done. Believe it or not i've gotten home from vacation so that's why i havent been here. Since im already very new to C++ and i just got home from vacation my brain is other places than C++ right now. Right now im actually just making sure that there are no errors or loopholes which is why i asked for the leapyear thing.

1
2
3
4
5
6
7
8
bool leapyear = checkLeapYear(year);


bool checkLeapYear(unsigned const year)
{
    return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
}
as far as the februrary thing..you can figure that out I think but if not month == 2


Some things in this confuses me i'll have to read a bit more before i can tell you the outcome, as i said im very new to programming.
You could do it the same as Disch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
bool isLeapYear(int year)
{
    if(year < 0)        return false;   // <- can't have negative months years wtf

    // years not divisible by 4 are never leap years
    if(year % 4)        return false;

    // years divisible by 400 are always leap years
    if(!(year % 400))   return true;

    // other years divisible by 100 are never leap years
    if(!(year % 100))   return false;

    // if we made it here, this is a leap year
    return true;
}
I just combined then all into one statement. Though, I just assumed they would put in an AD year and not BC.
Last edited on
So is it possible from here to create a statement which says if the isLeapYear variable is true and month is 2 then it's possible to have the everything from 29 and down to 1? Isn't there something which would equal to and in C++?
Last edited on
Ugh...look at the post I made earlier that you quoted. year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)

&& is the and operator.
Okay. About the code Disch wrote
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
bool isLeapYear(int year)
{
    if(year < 0)        return false;   // <- can't have negative months years wtf

    // years not divisible by 4 are never leap years
    if(year % 4)        return false;

    // years divisible by 400 are always leap years
    if(!(year % 400))   return true;

    // other years divisible by 100 are never leap years
    if(!(year % 100))   return false;

    // if we made it here, this is a leap year
    return true;
}


It doesn't seem to work for me it says a function-definition is not allowed here before '{ ' token. If i remove the bool variable it works but then the if statements are assigned to a variable which would make my job a whole lot harder
Last edited on
1) Disch wrote that.

2) It sounds like you are trying to declare the function inside of another. You must declare the function outside of it.

Would you show the full code please?
I didn't want to post the whole code so i just posted what was around the same area where the error occurs.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
 if (cYear <0)
  {
      cout << "The program will shutdown, next time type in a valid number";
      return 0;
  }

  cout << "Type in the current month number: " ;
  cin >> cMonth;
  
  
if (cMonth > 12)
{
    cout << "The program will shutdown, next time type in a valid number";
return 0;

}
if (cMonth <= 0)
{
    cout << "The program will shutdown, next time type in a valid number";
    return 0;
}

bool isLeapYear(int cYear)
{



    if(cYear < 0)        return false;   // <- can't have negative months years wtf

    // years not divisible by 4 are never leap years
    if(cYear % 4)        return false;

    // years divisible by 400 are always leap years
    if(!(cYear % 400))   return true;

    // other years divisible by 100 are never leap years
    if(!(cYear % 100))   return false;

    // if we made it here, this is a leap year
    return true;
}


if (cMonth <= 0)

{


        cout << "The program will shutdown, next time type in a valid number";
        return 0;


}




  cout << "Type in the current day: ";
  cin >> cDay;

  if (cDay > 31)
{
     cout << "The program will shutdown, next time type in a valid number";
return 0;
}
Yep, it was what I thought you have the function inside of the other one.

Move it outside


1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>

void someFunction(); //prototype

int main()
{
     someFunction(); //calling function, you would put params in the parenthesis
}

void someFunction() //definition
{
    std::cout << "Some function has been called." << std::endl;
}
Some function has been called.

Then what do i need to use the bool isLeapYear(int cYear); for since it isn't assigned to anything i was hoping i could assign the
1
2
3
4
5
6
7
8
9
10
11
12
13
if(cYear < 0)        return false;   // <- can't have negative months years wtf

    // years not divisible by 4 are never leap years
    if(cYear % 4)        return false;

    // years divisible by 400 are always leap years
    if(!(cYear % 400))   return true;

    // other years divisible by 100 are never leap years
    if(!(cYear % 100))   return false;

    // if we made it here, this is a leap year
    return true;


to the bool isLeapYear(int cYear) variable and then after that make an if statement that if isLeapYear is true and the month is 2 then it can be anything from the 29 and down
bool isLeapYear(int cYear); this is the function. It has a return type of bool a name of isLeapYear and one parameter of type int.

You would call it in the main function and assign it to a variable or just throw it in an if statement
1
2
3
4
5
6
7
8
bool leapyear = isLeapYear(year);

//or

if(isLeapYear(year))
{
    //do something
}


I think you need to give these a read to learn more about functions
http://www.cplusplus.com/doc/tutorial/functions/
http://www.learncpp.com/ <--chapter 7
Though, I just assumed they would put in an AD year and not BC.


Hmmm, according to google, leap years began in 45 BC.
Pages: 1234