我正在进行一些编程练习,其中一个涉及从头开始实现日期类对象。
总的来说,它的类设计和实现部分是小菜一碟,但是在日期输入和复制到私有数据成员期间出现了麻烦。
日期输入法必须采用MM / DD / YY格式,而班级数据成员必须是三种int类型(月,日,年)才能进行练习。
所以我的实现包括使用cin将输入转换为字符数组,然后将这些数组元素转换为类数据成员的int数据类型。
最初我想分别取每个数字列,将十位数乘以十并添加一列以获取int,但由于你仍在对字符数据类型进行数学操作,因此没有平移。
我确实找到了一个解决方案,但它确实是一个很好的解决方案,我觉得这样做会有更好,更有说服力的方式。
另外作为旁注,我想知道是否有人可以告诉我为什么我在运行时遇到堆栈溢出错误,当我将char数组大小从9减少到8.我认为char数组只需要大小+ 1 \ 0字符。根据我的统计,我应该对temp [8]有好处共9个点(2天2个月2年和2/1和0 = 9)我确定我在这里遗漏了一些东西。无论如何,如果重要的话,我正在为我的编译器使用VC ++ 2008。
#include <iostream>
#include <iomanip>
using std::cout;
using std::endl;
using std::cin;
//---------------------------------------------------------------------------
class date {
private:
int day, month, year;
public:
date() : day(0), month(0), year(0) {};
void getDate(char*);
void showDate();
int chartoint(char);
};
int date::chartoint(char a) {
switch(a) {
case '0': return 0;
case '1': return 1;
case '2': return 2;
case '3': return 3;
case '4': return 4;
case '5': return 5;
case '6': return 6;
case '7': return 7;
case '8': return 8;
case '9': return 9;
};
};
void date::getDate(char dArray[]) {
day=(chartoint(dArray[3])*10+chartoint(dArray[4]));
month=(chartoint(dArray[0])*10+chartoint(dArray[1]));
year=(chartoint(dArray[6])*10+chartoint(dArray[7]));
};
void date::showDate()
{
cout << std::setiosflags(std::ios::fixed | std::ios::showpoint);
(month<10) ? cout << std::setw(2) << std::setfill('0') << month : cout << month;
cout << "/";
(day<10) ? cout << std::setw(2) << std::setfill('0') << day : cout << day;
cout << "/";
(year<10) ? cout << std::setw(2) << std::setfill('0') << year : cout << year;
cout << endl;
};
//---------------------------------------------------------------------------
int main()
{
date a;
char temp[9];
cout << "Enter Date (mm/dd/yy): ";
cin >> temp;
a.getDate(temp);
a.showDate();
return 0;
}
答案 0 :(得分:4)
看来,最简单的方法是读入int
个变量并跳过分隔/
个字符。也就是说,您将定义一个输入运算符:
std::istream& operator>> (std::istream& in, date& value) {
// read the value for a date
return in;
}
你在一个char
数组中读取一个字符串,你需要确保不要试图存储比char
数组中的空格更多的字符。此外,您应始终验证阅读是否成功:
if (std::cin >> std::setw(sizeof(temp) >> temp) {
// process the read characters
}
请注意:不要试图像sizeof()
一样使用指向char
数组的指针:它将确定指针的大小,而不是指向数组的大小
BTW,您正确地计算出存储日期及其终止空字符需要9 char
s。为什么你认为它们适合8 char
s?
答案 1 :(得分:3)
非常简单的解决方案(尽管C风格)是使用函数sscanf()
直接从int
阅读char*
:
void date::getDate(const char *sDate) // const = "getDate will not change sDate"
{
sscanf(sDate, "%d/%d/%d", &month, &day, &year);
};
C ++解决方案将使用std::string
而不是char*
,因此主体应该如下所示:
date a;
std::string temp;
cout << "Enter Date (mm/dd/yy): ";
cin >> temp;
a.getDate(temp);
a.showDate();
然后您的getDate
方法可以引用std::string
对象,这不会改变,换句话说const std::string&
。要从std::string
读取值,您可以构建std::istringstream
对象,然后:
#include <sstream>
...
void date::getDate(const std::string& sDate)
{
std::istringstream ssDate(sDate);
ssDate >> month;
ssDate.ignore();
ssDate >> day;
ssDate.ignore();
ssDate >> year;
};
另请注意,方法chartoint
是多余的,showDate()
可能很简单:
void date::showDate()
{
cout << std::setw(2) << std::setfill('0') << month << '/';
cout << std::setw(2) << std::setfill('0') << day << '/';
cout << std::setw(2) << std::setfill('0') << year << endl;
};
答案 2 :(得分:1)
这是使用std :: stringstream:
的解决方案#include <iostream>
#include <iomanip>
#include <sstream>
using std::cout;
using std::endl;
using std::cin;
using std::stringstream;
//---------------------------------------------------------------------------
class date {
private:
int day, month, year;
public:
date() : day(0), month(0), year(0) {};
void getDate(char*);
void showDate();
};
void date::getDate(char dArray[]) {
std::stringstream ss(dArray);
ss>>month;
ss.ignore();
ss>>day;
ss.ignore();
ss>>year;
};
void date::showDate()
{
cout << std::setiosflags(std::ios::fixed | std::ios::showpoint);
(month<10) ? cout << std::setw(2) << std::setfill('0') << month : cout << month;
cout << "/";
(day<10) ? cout << std::setw(2) << std::setfill('0') << day : cout << day;
cout << "/";
(year<10) ? cout << std::setw(2) << std::setfill('0') << year : cout << year;
cout << endl;
};
//---------------------------------------------------------------------------
int main()
{
date a;
char temp[9];
cout << "Enter Date (mm/dd/yy): ";
cin >> temp;
a.getDate(temp);
a.showDate();
return 0;
}
编写mapoint函数的一种较短的方法是利用ASCII中0-9连续布局的事实:
int date::chartoint(char a) {
return a-'0';
};
另请注意,声明数组时,[]内的值实际上是SIZE,而不是最后一个合法索引。因此,temp [8]的数组声明仅在索引0-7中保存8个值。