Page 1 of 2 [ 17 posts ]  Go to page 1, 2  Next

Blake_be_cool
Veteran
Veteran

User avatar

Joined: 6 May 2008
Age: 27
Gender: Male
Posts: 860
Location: Australia, NSW, Sydney

28 Dec 2010, 3:39 am

Hey every one, I am a beginner C++ Programmer. I am currently stuck on this program I started from scratch. Because how I learn C++ is that I find codes and either just learn from seeing how they work or re-type them in my own way. For this one I am doing my own little project on telling people their current age. The only maths problem is: If the date is before there birthday it has -(numerals).

How do I fix this?

Quote:
/*
Name: What Is Your DOB?
Copyright: None
Author: Blake Reilly
Date: 03/12/10 17:47
Description: This is a simple program to get and calculate the data to find out someones current age.
*/


#include <iostream>

using namespace std;

int main()
{
int Y; // The Year
int YY; // The Year (Maths)
int YYY; // The Year (Current)
int M; // The Month
int MM; // The Month (Maths)
int MMM; // The Month (Current)
int D; // The Day
int DD; // The Day (Maths)
int DDD; // The Day (Current)



// The Date.
cout << "This is a progran to tell how old you are..." << endl;
cout << "Please enter the current date. (In Numeral)" << endl;
system ("PAUSE");
cout << "" << endl;
cout << "" << endl;
cout << "Enter the current year: ";
cin >> YYY; // Enter current year of date and hold in YYY.
cout << "Enter the current month: ";
cin >> MMM; // Enter current month of date and hold in MMM.
cout << "Enter the current day: ";
cin >> DDD; // Enter current day of date and hold in DDD.

cout << "" << endl;
cout << "" << endl;


// The DOB.
cout << "Please enter your DOB." << endl;
cout << "Year: ";
cin >> YY; // Enter year of birth and hold in YY.
cout << "Month: ";
cin >> MM; // Enter month of birth and hold in MM.
cout << "Day: ";
cin >> DD; // Enter day of birth and hold in DD.
Y = (YYY - YY); // Year(Y) = Date(YYY) - Birth(YY).
M = (MMM - MM); // Month(M) = Date(MMM) - Birth(MM).
D = (DDD - DD); // Day(D) = Date(DDD) - Birth(DD).
cout << "" << endl;
cout << "You are " << Y << "/" << M << "/" << D << " years old." << endl; // Result.
system ("PAUSE");
return 0;
}


_________________
"Not everything that steps out of line, and thus 'abnormal', must necessarily be 'inferior'."
- Hans Asperger (1938)


sessyargc
Emu Egg
Emu Egg

User avatar

Joined: 2 Nov 2007
Gender: Male
Posts: 7
Location: Setagaya-ku, Tokyo-to, Japan

28 Dec 2010, 3:57 am

You can do several things.
1) Do a check for the negative value.You can then discard the value and request another number. A simple loop would suffice.
2) OR use the function abs(), which should give you the absolute value of the number.

HTH



Roxas_XIII
Veteran
Veteran

User avatar

Joined: 8 Jan 2007
Age: 33
Gender: Male
Posts: 3,217
Location: Laramie, WY

28 Dec 2010, 4:22 am

Here's your problem. If someone tries to enter in a current date that is before their birth date, the result comes out negative which is why you have the dashes, they denote negative numbers. However, there shouldn't be negative numbers within the result, for the obvious reason that the current date will always be after your birth date.

The easiest way to fix this is to add some kind of control statement. The best one for this particular situation would be an if-else statement, which goes a little something like this:


Code:
...
if([boolean(true or false) statement]) {
[execute this if true]
} else {
[execute this if false]
}


Also, your math does not account for carrying months and days. Say I was born on March 5, 1991, but the current date is Feburary 25, 2011. Your math has it set up so that 2/26/2011 is subtracted from 3/5/1991, the result being -21 days, 1 month and 20 years, when the result should be 24 days, 11 months and 19 years.

If the goal of your program is to tell the user how old they are by the difference between the current date and their birth date, it would probably be easier to do so by going by the number of days since their birth. It's a little complicated, but the idea is simple: you take the number of years that have passed since their birth, and multiply it by 365. Then you take the years and divide it by 4, then add that number to the days to account for leap year. From there you take the difference in months, the easiest way being to take the number of days that have passed in the year since the beginning of the month (i.e. for Feburary 1 it would be 31), for both dates and then subtract. Take the resulting number and add to the days you have from the year difference, then take the difference of the day value between the two dates and add that. The result should be the total number of days that have passed since the person was born. From there you can calculate the years, months, and days.

Tell you what, I'm gonna write this up in Visual Studio and post it here, so you can see how it's done.


_________________
"Yeah, so this one time, I tried playing poker with tarot cards... got a full house, and about four people died." ~ Unknown comedian

Happy New Year from WP's resident fortune-teller! May the cards be ever in your favor.


Blake_be_cool
Veteran
Veteran

User avatar

Joined: 6 May 2008
Age: 27
Gender: Male
Posts: 860
Location: Australia, NSW, Sydney

28 Dec 2010, 4:37 am

Roxas_XIII wrote:
Tell you what, I'm gonna write this up in Visual Studio and post it here, so you can see how it's done.


Thanks, I hope to learn a lot from it.


_________________
"Not everything that steps out of line, and thus 'abnormal', must necessarily be 'inferior'."
- Hans Asperger (1938)


Roxas_XIII
Veteran
Veteran

User avatar

Joined: 8 Jan 2007
Age: 33
Gender: Male
Posts: 3,217
Location: Laramie, WY

28 Dec 2010, 5:04 am

Here you go. I'm not very good at leaving comments unfortunately, but I've tested this one and it works. If you want you can copy paste it into Visual Studio or whatever you use as a development environment and run the debugger. It should give you an idea of the math required. I find that, like you, looking at other people's code is a great way to learn new techniques.

Note that this is the simplest version I could come up with. I was thinking about using regular expressions to parse a standard date string (MM/DD/YYYY), but that's a whole different bag of tricks. If you're interested I can show you that too, but not tonight.

Code:
//AgeCalculator.cpp
//Calculates a person's age in years, months, and days using the current date and the person's birth date.
//K.S. (Roxas_XIII)
//December 28, 2010

#include <iostream>
using std::cin;
using std::cout;
using std::endl;

const int MTHS[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

int main()
{
   int yy, yyy, mm, mmm, dd, ddd;
   cout << "Input your birth date (year, month, day):" << endl;
   cin >> yy;
   cin >> mm;
   cin >> dd;
   cout << "Input the current date (year, month, day):" << endl;
   cin >> yyy;
   cin >> mmm;
   cin >> ddd;

   int y = yyy - yy;
   int d = y*365 + y/4;
   int m1 = 0;
   int m2 = 0;
   for(int i=0; i < mmm; i++) {
      m1 += MTHS[i];
      if(yyy % 4 == 0 && mmm > 2) {
         m1 += 1;
      }
   }
   for(int i=0; i < mm; i++) {
      m2 += MTHS[i];
      if(yy % 4 == 0 && mm > 2) {
         m2 += 1;
      }
   }
   int m = m1 - m2;
   d += m;
   d += ddd - dd;

   if(d < 0) {
      cout << "ERROR: current date is before birth date, please try again.";
      exit(1);
   }

   y = d / 365;
   d = d % 365;
   d -= y/4;
   int i = 0;
   m = 0;
   while(d > MTHS[i]) {
      d -= MTHS[i];
      m++;
      i++;
   }
   cout << endl << "You are " << y << " years,  " << m << " months, and " << d << " days old." << endl;
   return 0;
}


A few notes:

The '%' operator is the modulus operator. It's similar to the division operator '/', but returns the remainder of the division operation instead of the quotient. So, 11/4 would return 2, but 11%4 would return 3 (4 goes into 11 2 times (8) with 3 left over)

The constant array at the top contains the number of days in each month.

In a few places, you'll notice that I added or subtracted y/4 days. This is to account for leap year which occurs on years divisible by 4 (2000, 2004, 2008, etc.). Also, the if statment within the two for loops...

Code:
 if(y % 4 == 0 && mmm < 2)


... also accounts for leap year, by adding 1 to the day count if the current year is divisble by 4 and the current month is March or later (since leap day is added between February and March.)


_________________
"Yeah, so this one time, I tried playing poker with tarot cards... got a full house, and about four people died." ~ Unknown comedian

Happy New Year from WP's resident fortune-teller! May the cards be ever in your favor.


Blake_be_cool
Veteran
Veteran

User avatar

Joined: 6 May 2008
Age: 27
Gender: Male
Posts: 860
Location: Australia, NSW, Sydney

28 Dec 2010, 5:47 am

Thank you for this code.
I don't understand all of it... But, I'm studying it.


_________________
"Not everything that steps out of line, and thus 'abnormal', must necessarily be 'inferior'."
- Hans Asperger (1938)


Blake_be_cool
Veteran
Veteran

User avatar

Joined: 6 May 2008
Age: 27
Gender: Male
Posts: 860
Location: Australia, NSW, Sydney

28 Dec 2010, 6:09 am

Questions:

What is this and it's purpose:

Quote:
using std::cin;
using std::cout;
using std::endl;


Quote:
const int MTHS[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};


_________________
"Not everything that steps out of line, and thus 'abnormal', must necessarily be 'inferior'."
- Hans Asperger (1938)


emjay89
Yellow-bellied Woodpecker
Yellow-bellied Woodpecker

User avatar

Joined: 4 Nov 2010
Gender: Male
Posts: 67

28 Dec 2010, 6:29 am

wouldn't it just be easier to go:

#include <iostream>
using namespace std;

instead of using std::cin etc



Blake_be_cool
Veteran
Veteran

User avatar

Joined: 6 May 2008
Age: 27
Gender: Male
Posts: 860
Location: Australia, NSW, Sydney

28 Dec 2010, 6:31 am

emjay89 wrote:
wouldn't it just be easier to go:

#include <iostream>
using namespace std;

instead of using std::cin etc


That is what I do in mine;


_________________
"Not everything that steps out of line, and thus 'abnormal', must necessarily be 'inferior'."
- Hans Asperger (1938)


AspergianSuperstar
Tufted Titmouse
Tufted Titmouse

User avatar

Joined: 20 Dec 2010
Gender: Male
Posts: 43

28 Dec 2010, 11:49 am

Hello all,

Im trying to learn how to program, how do I get started with C++ or another language.

I really want to learn,,,



Roxas_XIII
Veteran
Veteran

User avatar

Joined: 8 Jan 2007
Age: 33
Gender: Male
Posts: 3,217
Location: Laramie, WY

28 Dec 2010, 6:53 pm

Blake_be_cool wrote:
Questions:

What is this and it's purpose:

Quote:
using std::cin;
using std::cout;
using std::endl;


Quote:
const int MTHS[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};


The first block is simply declaring the functions from the <iostream> library that will be used. I could declare the entire namespace as you did, but it would require less memory simply to declare the functions I would need. In a program this small it doesn't make any difference, but later on when you're programming multiple objects using hundreds of files, it can help shave off memory and cache requirements for your program.

As for the second block, I simply declared a constant array of integers to represent the number of days in each month out of the year. Since the array is declared as a constant, it cannot be changed once declared. Also, declaring it outside of any defined function means it can be used by any function in that particular file (though the only one that exists is the main function). I can then use it to recall the number of days in a specific month by using the syntax MTHS[i], where i is an integer from 0 to 11 (when referencing arrays, the first entry is always 0, and the last entry is always one less than the size of the array.) So, say I wanted to know how many days were in the month of March, I could retrieve that information from the array using the syntax MTHS[m - 1] where M is 3 (since March is the 3rd month of the year)


_________________
"Yeah, so this one time, I tried playing poker with tarot cards... got a full house, and about four people died." ~ Unknown comedian

Happy New Year from WP's resident fortune-teller! May the cards be ever in your favor.


mcg
Veteran
Veteran

User avatar

Joined: 26 Jan 2010
Age: 34
Gender: Male
Posts: 538
Location: Sacramento

28 Dec 2010, 7:53 pm

Roxas_XIII wrote:
The first block is simply declaring the functions from the <iostream> library that will be used. I could declare the entire namespace as you did, but it would require less memory simply to declare the functions I would need. In a program this small it doesn't make any difference, but later on when you're programming multiple objects using hundreds of files, it can help shave off memory and cache requirements for your program.
Nope, namespaces are just used by the compiler for scoping. Using namespaces does not incur any run time overhead, it's just a name that gets incorporated into the name decoration for symbols in the object file. If you had compiled your program with using namespace std; the compiled binary would be functionally identical to what you currently have (try running them through a bindiff program).

Linux command of the day: nm (part of binultils)

It lists all the symbols in an object file, so you can look and see how functions that are part of namespace get that namepsace incorporated into their decorated name. Pipe the output of nm to c++filt (also part of binutils) to see the unmangled names.



Blake_be_cool
Veteran
Veteran

User avatar

Joined: 6 May 2008
Age: 27
Gender: Male
Posts: 860
Location: Australia, NSW, Sydney

04 Jan 2011, 1:15 am

What About This Older One:

Quote:
#include <cstdlib>
#include <iostream>

using namespace std;

int main()
{

int a, b, A, B, answer;
a = 1;
A = 1;
b = 2;
B = 2;


cout << "Is Blake Awesome?" << endl;
cout << "A = Yes, B = No" << endl;
cin >> answer;



if (answer != 1,2)

{
cout << "Only Letters 'A or B' Mey Be Taken As An Answer." << endl;

}


else

{
cout << "Thank for you answer." << endl;

}


system("PAUSE");
return (0);

}


Why Doesn't It Work?


_________________
"Not everything that steps out of line, and thus 'abnormal', must necessarily be 'inferior'."
- Hans Asperger (1938)


ruveyn
Veteran
Veteran

User avatar

Joined: 21 Sep 2008
Age: 87
Gender: Male
Posts: 31,502
Location: New Jersey

04 Jan 2011, 5:34 am

My D.O.B is 2428404.94056



Blake_be_cool
Veteran
Veteran

User avatar

Joined: 6 May 2008
Age: 27
Gender: Male
Posts: 860
Location: Australia, NSW, Sydney

04 Jan 2011, 5:44 am

ruveyn wrote:
My D.O.B is 2428404.94056


What?

LOL


_________________
"Not everything that steps out of line, and thus 'abnormal', must necessarily be 'inferior'."
- Hans Asperger (1938)


milli
Tufted Titmouse
Tufted Titmouse

User avatar

Joined: 2 Jan 2011
Age: 36
Gender: Female
Posts: 36

04 Jan 2011, 6:03 am

This will work:

Quote:
#include <iostream>
#include <string>

using namespace std;

int main()
{

int a, b, answer;
a = 1;
b = 2;
answer = -1;

char test;
cout << "Is Blake Awesome?" << endl;
cout << "A = Yes, B = No" << endl;
cin >> test;

if(tolower(test) == 'a')
answer = a;
else if(tolower(test) == 'b')
answer = b;


if (answer == 1 || answer == 2){
cout << "Thank for you answer." << endl;
}

else{
cout << "Only Letters 'A or B' Mey Be Taken As An Answer." << endl;
}


system("PAUSE");
return (0);

}



You did not give your "answer" the correct value.


I'm not familiar with your way to write if-sentences.
This will also work:
if (answer != 1 && answer != 2){
cout << "Only Letters 'A or B' Mey Be Taken As An Answer." << endl;
}

else{
cout << "Thank for you answer." << endl;
}



If I should write a program like this for my own, I wouldt probably do it in an other way. I made it that way so that it would not vary so much from yours.



Last edited by milli on 04 Jan 2011, 7:24 am, edited 1 time in total.