ifstream — C ++ Создание объекта из текстового файла

Для начала позвольте мне поблагодарить людей, которые часто пишут здесь, за последние несколько лет я приобрел массу знаний по поиску на этом сайте.

Хорошо, этот вопрос был задан ранее, но у меня есть небольшой поворот, который я не могу заставить работать.

Вот моя структура.

struct person
{
string Sex;
string Name;
string Match;
int phoneNumber;
int numInterests;
vector<string> interests;
};

Задание выполнено в виде «Программы знакомств», которая сопоставляет людей противоположного пола со схожими интересами.

Вот пример текстового файла следующего формата:

«Пол» «Имя» «Номер телефона» «Количество интересов» «Список интересов» «Совпадение (если совпадение найдено)»

M Tyler 1234567890 3 soccer football tv Jess
F Lyns 1234567890 3 hockey sex movies
F Jess 1234567890 3 soccer football tv Tyler
M Taylor 1234567890 3 hockey sex movies

В этом файле примера есть совпадение для Джесс и Тайлер.
Вот моя функция до сих пор …

void LoadClients(std::ifstream &file,vector<person>& peps)
{
string sex,name,interests,line, match;
double phone,ni;
person p;
for(int i=0;i<maxPeople("Clients.mf"); i++){
file>>sex>>name>>phone>>ni;
p.Sex = sex;
p.Name = name;
p.phoneNumber = phone;
p.numInterests = ni;
for (int i=0; i<ni; i++){
file >> line;
p.interests.push_back(line);
}
file >> match;
p.Match = match;
peps.push_back(p);

// person p;
//istringstream iss( line );
}

};

Функция компилируется, но вообще не читает правильно. Вот остальная часть моей работы, на случай, если вы захотите ее увидеть …

int maxPeople(const char* file)///Just returns the number of lines in the file
{
ifstream inFile(file);
int c = count(istreambuf_iterator<char>(inFile),
istreambuf_iterator<char>(), '\n');
return c;
}
int main()
{
int numberOfClients=maxPeople("Clients.mf");
ifstream file("Clients.mf");

vector<person> peps;
LoadClients(file,peps);

return 0;
}

Моя функция LoadClients была смоделирована после элегантного ответа, который я нашел здесь: Чтение строки и целых чисел

Все, о чем я прошу, — как заставить эту функцию создавать вектор или массив людей из текстового файла.

Конечная программа будет иметь дополнительные функции «NewClient», «UnMatch», «PrintMatched» и «PrintSingles», но я думаю, что справлюсь с ними. Любые советы приветствуются 🙂

Спасибо за прочтение!

EDIT1:
Используя этот формат.

void LoadClients(std::ifstream &file,vector<person>& peps)
{
person p;
string line;
while( getline( file, line ) )
{
istringstream iss( line );
iss >> p.Sex >> p.Name >> p.phoneNumber >> p.numInterests;
for(int i=0;i<p.numInterests;i++){
string interest;
iss >> interest;
p.interests.push_back(interest);
}

}
};

Я решил пока пропустить «матч». Я получаю ошибку сегментации при доступе к объектам из main.

ifstream file("Clients.mf");

vector<person> peps;
LoadClients(file,peps);
for(int i=0; i<numberOfClients;i++){
cout << peps[0].Name;
}

1

Решение

Кстати, это не хорошая идея для sex быть string, если вы не хотите, чтобы ваша программа работала с инопланетянами … И у вас могут быть проблемы с вашим int phoneNumbers. А также numInterests избыточно, если у вас есть interests.size(), Так что вы можете сделать …

struct Person {
enum class Gender {
Unknown,
Male,
Female,
};

Gender gender;
std::string name;
std::string match;
std::string phoneNumber;
std::vector<std::string> interests;
};

Теперь к проблеме. Функция должна выглядеть следующим образом (без проверки и C ++ 11!) …

static Person::Gender readGender(std::ifstream &input) {
char ch;
input >> ch;
switch(ch) {
case 'M':
return Person::Gender::Male;

case 'F':
return Person::Gender::Female;

default:
return Person::Gender::Unknown;
}
}

void LoadClients(std::ifstream &file, std::vector<person> &out) {
for(int i = 0; i < maxPeople("Clients.mf"); i++) {
Person p;
unsigned numInterests;

p.gender = readGender(file);
file >> p.name;
file >> p.phoneNumber;
file >> numInterests;
for(unsigned i = 0; i < numInterests; i++){
std::string interest;
file >> interest;

p.interests.push_back(interest);
}

file >> p.match;
out.push_back(p);
}
}

редактировать: У вас должны быть средства, чтобы программа могла определить, есть ли match или нет, в противном случае неопределенное разочарование будет искать вас!

редактировать: Недействительный предыдущий комментарий из-за комментариев от OP.

редактировать: Исправлено несколько ошибок в соответствии с комментариями.

1

Другие решения

Поскольку ваши входные данные основаны на строках, используйте считыватель на основе строк. Проблема с программой сейчас в том, что она предполагает, что всегда есть совпадение. Но во второй строке входного файла совпадений нет. Следовательно, следующий текст, разделенный пробелами, будет прочитан.

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

string line;
while( getline( file, line ) )
{
istringstream iss( line );

// Now, parse out of 'iss' instead of 'file'.
person p;
bool ok = false;
if( iss >> p.Sex >> p.Name >> p.phoneNumber >> p.numInterests )
{
p.interests.reserve( p.numInterests );
for( int i = 0; i < p.numInterests; i++ )
{
string interest;
if( iss >> interest ) p.interests.emplace_back( interest );
}

ok = !iss.error();

iss >> p.Match; // optional
}

if( ok ) peps.push_back( p );
}

Вы можете пойти еще дальше и определить оператор ввода потока для вашего Person структура. Тогда основной цикл чтения будет выглядеть так:

person p;
iss >> p;
3

Телефон и номер телефона (я полагаю, это число интересов) не должны быть двойными. Я бы сделал Phone строкой и ni int (некоторые утверждали бы, что без знака, но достаточно близко).

Double и Float — это типы данных с потерями, которые не подходят для счета или номера телефона.

Вы на самом деле не говорите, что такое поведение и что вы ожидаете от него.
Я предполагаю, что ваша нагрузка становится плохой, и это из-за этой строки:

file >> match;

Вы не знаете, есть ли строка в этой строке или нет, поэтому она может поднять первую работу следующей строки.

Я бы переключился на использование getLine и потока строк и проверил, пуста ли строка (поток строк IE в конце или нет) перед извлечением соответствия.

1
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector