I’m doing an homework that require me to check if the Student is over 18.
My function is this:
bool Student::isOverEighteen() {
int date[3]; // D/M/Y
char *pdata;
pdata = strtok(Anagrafica::birth, "/"); // Anagrafica is the base class
for (short i = 0; pdata != NULL; i++) {
data[i] = pdata;
pdata = strtok(NULL, "/");
}
time_t t = time(NULL);
tm *locale = localtime(&t);
if (data[0] < locale->tm_mday &&
(data[1] < locale->tm_mon + 1 || data[1] == locale->tm_mon + 1) &&
(locale->tm_year + 1900 - data[3] > 18))
{
return true;
} else {
return false;
}
}
However, when I display the date of birth it show me the date plus the classroom of the student. For example: 25/06/19944A (4A is the name of the classroom)
The function that I use to register students information:
Student::Student() {
std::cout << "Name: ";
std::cin.getline(Anagrafica::name, 101);
std::cout << "Surname: ";
std::cin.getline(Anagrafica::surname, 101);
std::cout << "Birth (XX/XX/XXXX): ";
std::cin.getline(Anagrafica::birth, 11);
std::cout << "Classroom: ";
std::cin.getline(Anagrafica::classroom, 101);
}
The function for displaying them:
void Anagrafica::Show() {
std::cout << "\nName:" << this->name;
std::cout << "\nSurname:" << this->surname;
std::cout << "\nBirth:" << this->birth;
std::cout << "\nClassroom: " << this->classroom;
std::cout << std::endl;
}
And they are declared:
char name[100];
char surname[100];
char birth[10];
char classroom[100];
Any solution for making this working?
EDIT (for Nik Bougalis):
Here is the one I use now.
The problems with strings started because I was using c_str; instead of c_str();
bool Entry::IsOverEighteen() {
int date[3];
date[0] = std::atoi(this->birth.substr(0, 2).c_str()); // Day
date[1] = std::atoi(this->birth.substr(4, 2).c_str()); // Month
date[2] = std::atoi(this->birth.substr(6, 4).c_str()); // Year
time_t t = time(NULL);
tm *local = localtime(&t);
// Perche' sia maggiorenne occorre che:
// Il giorno attuale sia maggiore di quello di nascita
// Il mese attuale sia maggiore o uguale a quello di nascita
// L' anno attuale - l' anno di nascita sia maggiore o uguale 18
if (local->tm_mday > date[0] &&
(local->tm_mon + 1 > date[1] || local->tm_mon + 1 == date[1]) &&
(local->tm_year + 1900 - date[2] > 18 || local->tm_year + 1900 - date[2] == 18))
{
return true;
} else {
return false;
}
}
The problem is that your
char birth[10]is exactly as long as the string 25/06/1994 (i.e. 10 bytes) leaving no space for the NULL terminator, so when printing out thebirthstring, cout starts reading, continues past the end ofbirthand ontoclassroom.Also note that you consistently call
cin.getlinewith a buffer size that is one LARGER than the actual buffer. You’re in essence tellinggetline: “here’s a 10 byte buffer… read 11 bytes into it!” Is that what you really mean?All of this, of course, would not have happened if you used
std::stringinstead ofchar[]. Why didn’t you?Now, as far as
isOverEighteenis concerned: the function is completely broken, and in fact, the version you show here won’t even compile. Let’s see if we can go about fixing it.My first question, of course, would be why not simply have the birthday input as 3 integers directly instead of accepting it as a string? But let’s assume you can’t for your assignment. Try using this instead:
There are more elegant ways of doing this, and it’s not very “C++” but it works, which is an improvement.