ofstream ifilestream并使用cin获取一系列字符?

时间:2011-06-03 21:11:14

标签: c++ stl filesystems filestream

所以我正在学习如何使用流来制作我自己类型的文件,我有一个简单的版本就像这样工作

struct Appointment
{

Appointment()
{

}
// 

//and int to represent a certain doctor
int doctorID;  // an enum to be made later

int year; // 1950 - 2050    100 years total

int month; // 0 - 11  

int day; // 0 - 31   

int hour; // 0 - 23


int minute; // 0 - 59
    static Appointment GetDataFromUser()
{
    Appointment appoint = Appointment();

    cout << "\nEnter a Doctor ID :" << endl;
    cin >> appoint.doctorID;

    cout << "\nEnter a year 1900 - 3000 :" << endl;
    cin >> appoint.year;

    cout << "\nEnter a month 0 - 11 :" << endl;
    cin >> appoint.month;

    cout << "\nEnter a day of month 0 - 31 :" << endl;
    cin >> appoint.day;

    cout << "\nEnter an hour 0 - 23 :" << endl;
    cin >> appoint.hour;

    cout << "\nEnter an minute 0 - 59 :" << endl;
    cin >> appoint.minute;

    cout << "\nAll values entered thank you!" << endl;

    return appoint;

}
};

然后我用的地方

ifstream ifilestream( fileName.c_str(), std::ios_base::in | std::ios::binary );

Appointment appoint;

ifilestream.read((char *)&appoint, sizeof(Appointment));

ofstream ofilestream( fileName.c_str(), std::ios_base::out | std::ios::binary );

Appointment appoint = Appointment::GetDataFromUser();

ofilestream.write((char *)&appoint, sizeof(Appointment));

这样做没问题,但是我想用一个char doctorID [长度]长度= 20或者其他东西替换int doctorID,用医生名称和空格来存储。例如,用户可以输入“Dr. Watson”或“Watson”。

但是当我这样做并使用cin来获取该信息时,它会破坏空间的代码原因或者我不确定的任何内容。那么这样做的正确方法是什么?

第二个问题是,如果我想在用户输入时确定char []的长度怎么办?

2 个答案:

答案 0 :(得分:3)

要输入包含空格的字符串,请使用cin.getline(),它会读取换行符:

char doctorID[20]; 
...
cout << "\nEnter a Doctor ID :" << endl;
cin.getline(appoint.doctorID, 20);

如果你想要一个在运行时确定大小的字符串,你应该使用std::string,它可以动态调整大小。

但是,如果使用std::string,您将无法再按照现在的方式读取和写入文件结构。 (*)你可以:

  1. 切换到基于文本的文件 格式
  2. 编写自己的功能 用于序列化/反序列化 std::string到二进制文件
  3. 使用类似Boost.Serialization
  4. 的序列化库

    (*)因为现在你只是完全按照它在内存中的表示来编写结构;但是std :: string的表示实际上只是指向另一个内存位置的指针

答案 1 :(得分:1)

不要将结构重新解释为数据指针!这会将它绑定到当前编译器生成的任何内存中表示形式。如果你有任何关于你的程序的改变,你的流媒体将会破裂。

对于输出,第一步是编写operator<<(ostream& out, Appointment const& app);函数。通常,您希望这是一个免费的功能,是您班级的朋友

struct Appointment
{
    // previous contents
    friend ostream& operator<<(ostream& out, Appointment const& app);
};
ostream& operator<<(ostream& out, Appointment const& app)
{
    out << app.doctorID << std::endl;
    // out << app.OtherField for each field
    return out;
}

然后你可以ofilestream << appoint;。编写对称运算符以进行输入,但您可以忽略空格。使用std :: string而不是char []。 序列化最通用的解决方案是使用boost :: Serialization框架。但这个问题太过分了。