ofstream ifilestream и использование cin для получения массива символов? - PullRequest
2 голосов
/ 04 июня 2011

Итак, я учусь, как использовать потоки для создания файлов моего собственного типа, у меня есть простая версия, которая работает так:

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));

Это работает нормально, но я хочу заменить int doctorID на char char IDID длина [length] может = 20 или около того, чтобы сохранить имя доктора с пробелами и.Например, пользователь может ввести «Dr. Watson» или просто «Watson».

Но когда я делаю и использую cin для получения этой информации, это нарушает кодовую причину пробелов или что-то еще, в чем я не уверен.Так какой же правильный способ сделать это?

И второй вопрос: что, если бы я хотел, чтобы длина char [] была определена, когда пользователь вводит его?

Ответы [ 2 ]

3 голосов
/ 04 июня 2011

Чтобы ввести строку, содержащую пробелы, используйте 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

(*), потому что сейчас вы просто пишете структуру в точности так, как она представлена ​​в памяти;однако представление std :: string на самом деле является просто указателем на другое место в памяти

1 голос
/ 04 июня 2011

Не интерпретируйте свою структуру как указатель данных!Это связывает его с любым представлением в памяти, которое создает ваш текущий компилятор.Если вы когда-нибудь что-нибудь измените в своей программе, ваш поток будет прерван.

Для вывода первым шагом является написание функции 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.Но это излишне для этой проблемы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...