我正在做一个功课,要求我检查学生是否超过18岁.我的功能是这样的:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
但是,当我显示出生日期时,它会显示日期和学生的课堂.例如:25/06/19944A(4A是教室的名称)
我用来注册学生信息的功能:
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);
}
Run Code Online (Sandbox Code Playgroud)
显示它们的功能:
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;
}
Run Code Online (Sandbox Code Playgroud)
他们被宣布:
char name[100];
char surname[100];
char birth[10];
char classroom[100];
Run Code Online (Sandbox Code Playgroud)
任何使这个工作的解决方案?
编辑(对于Nik Bougalis):
这是我现在使用的那个.字符串的问题开始是因为我使用的是c_str; 而不是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;
}
}
Run Code Online (Sandbox Code Playgroud)
问题是你char birth[10]的字符串与字符串25/06/1994(即10个字节)完全一样长,没有为NULL终止符留出空间,因此当打印出birth字符串时,cout开始读取,继续经过结尾birth和之后classroom.
另请注意,您始终cin.getline使用比实际缓冲区大一个的缓冲区大小调用.你实质上在说getline:"这是一个10字节的缓冲区...读入11个字节!" 那是你真正的意思吗?
当然,如果您使用std::string而不是,那么所有这一切都不会发生char[].你为什么不呢?
现在,就此isOverEighteen而言:功能完全被破坏,事实上,你在这里显示的版本甚至都不会编译.让我们看看我们是否可以修复它.
我的第一个问题,当然,是为什么不只是有生日输入为3点的整数直接,而不是接受它作为一个字符串?但是我们假设你无法完成任务.请尝试使用此代码:
bool isOverEighteen(const string &s)
{ // s is in the form DD/MM/YYYY - if it's not, things blow up.
int birthday[3], bidx = 0;
birthday[0] = 0;
birthday[1] = 0;
birthday[2] = 0;
for(int i = 0; i != s.length(); i++)
{
if(s[i] == '/')
{
bidx++;
continue;
}
birthday[bidx] = (birthday[bidx] * 10) + (s[i] - '0');
}
// now birthday[0] is the day of birth as an integer,
// birthday[1] is the month of birth as an integer and
// birthday[2] is the year of birth as an integer. You
// can use them.
...
}
Run Code Online (Sandbox Code Playgroud)
有更优雅的方法,这不是很"C++",但它有效,这是一个改进.