Как сделать чтобы выводился самый молодой участник 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().

→ Ссылка