ОП не хочет менять файл, поэтому этот ответ больше не подходит. Работа в процессе.
Здесь есть две широкие стратегии
Мы можем выбрать:
- У пользователя отформатировать данные для нас.
- Программа отформатирует данные.
И затем мы их проанализируем.
1) Фиксированный формат данных :
Самое простое решение.
Заставьте пользователя вводить данные в формате, который может быть легко проанализирован . Здесь пользователь должен правильно вводить данные, и программа проверит правильность введенных данных. Это можно сделать разными способами, в том числе, но не полностью:
Peter-Richmond Barker 1234 5678 // hyphen(-) separated
"James Herbert" Bond 007 999 // enclosed in quotes("")
Barack_Hussein Obama 2007 14165 // underscore(_) separated
В первом и третьем случае достаточно std::cin >> person.first_names
.
Во втором случае вам придется
std::getline(std::cin, person.first_names, '\"'); // any character delimiter
это после проверки разделителя открывания с помощью std::cin.get() == '\"'
.
2) Медленно и устойчиво
Еще одно очень простое решение. Просто заставьте пользователя вводить одну вещь за раз :
std::cout << "Enter some datum 1: ";
std::cin >> person.some_datum_1;
...
(Вопреки распространенному мнению, данные единичны, а данные множественного числа ).
Для нескольких входов см. Токенизация линии :
Позвольте мне взять метод здесь:
std::cout << "Enter some data 1: ";
// Grab the line and put into a stream
std::getline(std::cin, line);
std::stringstream line_buffer(line);
// Prepare to iterate over the stream
std::istream_iterator<std::string> it(line_buffer);
std::istream_iterator<std::string> end;
// Set the name with a move assignment operator
person.first_names = std::move(std::vector<std::string>(it, end));
...
Обратите внимание, что этот метод потребует person.first_names
, чтобы быть std::vector<std::string>
.
3) Начало с конца
Здесь мы сначала вводим данные неопределенного размера.
Предупреждение : Это будет работать только для одного ввода неопределенного размера. Если имя и фамилия могут быть более двух, это не сработает. Я упоминаю об этом только для полноты.
Если вы не хотите принуждать пользователей к этому и портить им опыт, вам придется анализировать ввод самостоятельно. Введите всю строку со старым добрым std::getline(std::cin, line);
.
Инициализируйте int read_from = std::string::npos;
.
Теперь найдите последний пробел с помощью read_from = line.rfind(' ', read_from);
. read_from == std::string::npos
сообщит вам, что все входы были проанализированы или произошла ошибка.
A line.substr(read_from)
выбирает последний вход. Преобразуйте его в соответствующий тип и сохраните. Вам также придется стереть проанализированный вход с помощью line.resize(read_from);
Промыть и повторить для других входов.
Примечание : рекомендуется сохранить неопределенные данные в std::vector
соответствующего типа.
4) Марш байтов
Я знаю, вы бы сказали, что мы не рассмотрели вопрос ОП:
... читать в файле с личной информацией ...
Теперь, когда мы обсудили Принимая ввод от пользователя, мы также можем выбрать как , чтобы сохранить его (и получить его).
Самый простой способ:
personal_data_file.write((char*)&person_list[i], sizeof(Person)); // Write it...
personal_data_file.read((char*)&person_list[i], sizeof(Person)); // ...Now read it.
на всех oop, где person_list
- это std::vector
из Person
с.
Примечание : не забудьте открыть файл в режиме std::ios::binary
!
Elegant!
Но на всякий случай вы не знакомы с классами и некоторыми функциями, использованными в приведенных выше примерах. Вот несколько ссылок:
std :: getline https://www.geeksforgeeks.org/how-to-use-getline-in-c-when-there-are-black-lines-in-input/
std :: istream :: read http://www.cplusplus.com/reference/istream/istream/read/
std :: ostream :: write http://www.cplusplus.com/reference/ostream/ostream/write/
std :: vector https://www.geeksforgeeks.org/vector-in-cpp-stl/
std :: istream_iterator http://www.cplusplus.com/reference/iterator/istream_iterator/