Как сделать чтобы выводился самый молодой участник C++
Как сделать чтобы выводился самый молодой участник C++ в функции performTask(); в данный момент выводится наоборот, самый старый участник
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
#include <vector>
#include <algorithm>
const char* fileName = "contestants.bin";
struct Contestant {
char fullName[256];
int birthYear;
char country[256];
char instrument[256];
int place;
};
void createFile() {
std::ofstream file(fileName, std::ios::binary | std::ios::trunc);
if (!file.is_open()) {
std::cerr << "Error creating file." << std::endl;
return;
}
int numContestants;
std::cout << "Enter the number of contestants: ";
std::cin >> numContestants;
for (int i = 0; i < numContestants; ++i) {
Contestant contestant;
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // Clear input buffer
std::cout << "Enter full name: ";
std::cin.getline(contestant.fullName, sizeof(contestant.fullName));
std::cout << "Enter birth year: ";
std::cin >> contestant.birthYear;
std::cout << "Enter country: ";
std::cin >> contestant.country;
std::cout << "Enter musical instrument: ";
std::cin >> contestant.instrument;
std::cout << "Enter place on contest: ";
std::cin >> contestant.place;
file.write(reinterpret_cast<char*>(&contestant), sizeof(Contestant));
}
file.close();
}
void viewFile() {
std::ifstream file(fileName, std::ios::binary);
if (!file.is_open()) {
std::cerr << "Error opening file." << std::endl;
return;
}
Contestant contestant;
std::cout << std::setw(20) << "Full Name" << std::setw(10) << "Birth Year" << std::setw(15) << "Country"
<< std::setw(20) << "Instrument" << std::setw(10) << "Place" << std::endl;
std::cout << "-------------------------------------------------------------" << std::endl;
while (file.read(reinterpret_cast<char*>(&contestant), sizeof(Contestant))) {
std::cout << std::setw(20) << contestant.fullName << std::setw(10) << contestant.birthYear
<< std::setw(15) << contestant.country << std::setw(20) << contestant.instrument
<< std::setw(10) << contestant.place << std::endl;
}
file.close();
}
void updateFile() {
std::fstream file(fileName, std::ios::binary | std::ios::in | std::ios::out);
if (!file.is_open()) {
std::cerr << "Error opening file for updating." << std::endl;
return;
}
int recordNumber;
std::cout << "Enter the record number to update (starting from 1): ";
std::cin >> recordNumber;
// Move the file pointer to the record to be updated
file.seekg((recordNumber - 1) * sizeof(Contestant), std::ios::beg);
Contestant updatedContestant;
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // Clear input buffer
std::cout << "Enter updated full name: ";
std::cin.getline(updatedContestant.fullName, sizeof(updatedContestant.fullName));
std::cout << "Enter updated birth year: ";
std::cin >> updatedContestant.birthYear;
std::cout << "Enter updated country: ";
std::cin >> updatedContestant.country;
std::cout << "Enter updated musical instrument: ";
std::cin >> updatedContestant.instrument;
std::cout << "Enter updated place on contest: ";
std::cin >> updatedContestant.place;
// Write the updated record back to the file
file.write(reinterpret_cast<char*>(&updatedContestant), sizeof(Contestant));
file.close();
}
void performTask() {
std::ifstream file(fileName, std::ios::binary);
if (!file.is_open()) {
std::cerr << "Error opening file for task." << std::endl;
return;
}
Contestant youngestLaureate;
bool found = false;
while (file.read(reinterpret_cast<char*>(&youngestLaureate), sizeof(Contestant))) {
if (!found || youngestLaureate.birthYear > 0) {
youngestLaureate = youngestLaureate.birthYear > 0 ? youngestLaureate : Contestant{};
found = true;
}
if (youngestLaureate.birthYear > 0 && youngestLaureate.birthYear > youngestLaureate.birthYear) {
// Исправлено условие на >
youngestLaureate = youngestLaureate;
}
}
file.close();
if (found) {
std::cout << "The youngest laureate is: " << youngestLaureate.fullName << " (Birth Year: " << youngestLaureate.birthYear << ")\n";
} else {
std::cout << "No laureates found.\n";
}
}
bool compareByPlace(const Contestant& a, const Contestant& b) {
return a.place < b.place;
}
void sortByPlace() {
std::ifstream file(fileName, std::ios::binary);
if (!file.is_open()) {
std::cerr << "Error opening file for sorting." << std::endl;
return;
}
std::vector<Contestant> contestants;
Contestant contestant;
while (file.read(reinterpret_cast<char*>(&contestant), sizeof(Contestant))) {
contestants.push_back(contestant);
}
file.close();
std::sort(contestants.begin(), contestants.end(), compareByPlace);
std::cout << "Sorted data by place:\n";
std::cout << std::setw(20) << "Full Name" << std::setw(10) << "Birth Year" << std::setw(15) << "Country"
<< std::setw(20) << "Instrument" << std::setw(10) << "Place" << std::endl;
std::cout << "-------------------------------------------------------------" << std::endl;
for (const auto& c : contestants) {
std::cout << std::setw(20) << c.fullName << std::setw(10) << c.birthYear
<< std::setw(15) << c.country << std::setw(20) << c.instrument
<< std::setw(10) << c.place << std::endl;
}
}
int main() {
int choice;
do {
std::cout << "\n1 - Create new file\n";
std::cout << "2 - View file\n";
std::cout << "3 - Update file\n";
std::cout << "4 - Perform task\n";
std::cout << "5 - Sort by place\n";
std::cout << "6 - Exit\n";
std::cout << "Enter your choice: ";
std::cin >> choice;
switch (choice) {
case 1:
createFile();
break;
case 2:
viewFile();
break;
case 3:
updateFile();
break;
case 4:
performTask();
break;
case 5:
sortByPlace();
break;
case 6:
std::cout << "Exiting program.\n";
break;
default:
std::cout << "Invalid choice. Try again.\n";
break;
}
} while (choice != 6);
return 0;
}
Ответы (1 шт):
Автор решения: Swift - Friday Pie
→ Ссылка
Самая важная часть - сравнение, сделано неправильно - было сравнение с самим собой.
Contestant youngestLaureate {}, curLaureate {}; //инициализация!
if(file.read(reinterpret_cast<char*>(&youngestLaureate), sizeof(youngestLaureate )))
while (file.read(reinterpret_cast<char*>(&curLaureate), sizeof(curLaureate)))
{
if( curLaureate.birthYear < youngestLaureate.birthYear)
youngestLaureate = curLaureate;
}
}
ЗЫ: у меня большие сомнения по поводу while (file.read(reinterpret_cast<char*>(&youngestLaureate)). В реальной жизни такая сериализация никуда не годится. Да и лучше сделать функцию readRecord(Contestant&)
bool readRecord(std::istream& file, Contestant& val) {
if (file.eof()) return false;
return file.read(reinterpret_cast<char*>(&val), sizeof(val));
}
Достижение конца файла не является ошибкой потока, поэтому подход с прямой проверкой может работать не так, как надо. Нужно использовать .good() или явно .eof().