-3

I want to make a program that inputs data of participants in a txt file through the input function of the class. The output function is then used to extract the information of a single participant at a time by keying in their ID.

In this code of mine, my while loop runs infinitely as soon as I enter an ID. I suspect that it is unable to find the eof(). Any help would be greatly appreciated. I am new to C++.

#include <fstream>
#include <sstream>
#include <iostream>
#include <string>
using namespace std;

class Participant{
private:
    int id, score;
    string name;
public:
    Participant(){
        id = 0; score = 0; name = "";
    }
    void input(){
        char choice;
        ofstream in;
        in.open("Participant.txt", ios::app);

        do{

            cout<<"Enter your ID:   \t";
            cin>>id;
            cout<<"Enter your name: \t";
            cin>>name;
            cout<<"Enter your Score:\t";
            cin>>score;

            in<<name<<" ";
            in<<id<<" ";
            in<<score<<endl;

            cout<<"Add another entry? (Y/N)\n";
            cin>>choice;

        }while(choice == 'y' || choice == 'Y');

        in.close();
    }

    void output(){
        int idout, holderID, holderS;
        string holder, output;
        cout<<"Enter the ID for more information related to the person:"; 
        cin>>idout;

        fstream out;
        out.open("Participant.txt");

        while(!out.eof()){
            out>>holderID;
            cout<<"looping...\n";
            if(idout == holderID){
                out>>holder;
                cout<<"Name: \t"<<holder<<endl;
                out>>holderS;
                cout<<"Score:\t"<<holderS<<endl;
                holder ="";
                holderS=0;
                break;
            }
            else continue;
        }

        out.close();
    }

    void max(){

    }
};

int main(){
char choice;
Participant player;

cout<<"Asking for Input: \n";
player.input();



system("pause");
system("cls");

cout<<"Data Viewing: \n";
do{
    player.output();
    cout<<"\nDo you wish to extract information on other players?\n";
    cout<<"Y - Yes."<<endl;
    cout<<"N - No."<<endl;
    cout<<"Choice: ";
    cin>>choice;
}while (choice == 'y' || choice == 'Y');
cout<<"\n\nEnd of Data Viewing.\n";
}

I want it to, at first, read just the ID, in the first line its 1037. If the ID matches, it should display the next 2 members in the file; the name and the score.

  • This doesn't address the question, but get in the habit of initializing objects with meaningful values rather than default-initializing them and immediately writing the "proper" values. That is, change `ofstream in; in.open("Participant.txt", ios::app);` to `ofstream in("Participant.txt', ios::app);`. And you don't need to call `in.close();`. The destructor will do that. – Pete Becker Apr 22 '19 at 13:27

1 Answers1

0

The Problem is that you tried to use holderID (int) Directly from the out stream. Try to use string to read the same out value and use stoi() to convert the same to int. Also note as you write the first is name followed by id and score.

Also use the below as a reference. I have used std::map to store the value of id, name and score.

#include <string>
#include <fstream>
#include <map>
#include <iostream>
#include <algorithm>
#include <sstream>

class Participants
{
    int id;
    int score;
    std::string name;
public:
    Participants(): id(0), score(0)
    {}

    Participants(int id, int score, std::string name): id(id), score(score), name(name)
    {}

    ~Participants()
    {}

    int GetId()
    {
        return id;
    }

    std::string encode()
    {
        auto strRet = std::string( name + " " + std::to_string(id) + " " + std::to_string(score) + "\n");
        return  strRet;
    }

    void decode(std::string text)
    {
        std::stringstream ss(text);
        std::string buf;

        //Read Name
        std::getline( ss, buf , ' ');
        name = buf;

        //Read id
        std::getline( ss, buf , ' ');
        id = std::stoi( buf );

        //Read Score
        std::getline( ss, buf , '\n');
        score = std::stoi( buf );

    }
};

class DataReader
{
    std::string fileName;
    std::fstream myfile;

public:
    DataReader(std::string fileName): fileName(fileName)
    {

    }
    ~DataReader()
    {

    }

    void ReadParticipants(std::map<int, Participants> &MapParticipants)
    {
        myfile.open(fileName, std::ios::in);
        MapParticipants.clear();
        if ( myfile.is_open() )
        {
            std::string line;
            while ( std::getline(myfile, line) )
            {
                Participants oParticipants;
                //Decode and Add to map
                oParticipants.decode(line);
                //Add to map
                MapParticipants[ oParticipants.GetId() ] = oParticipants;
            }
        }
        myfile.close();
    }

    void WriteParticipants(std::map<int, Participants> &MapParticipants)
    {
        //Load Map to find Duplicates
        std::map<int, Participants> MapParticipants_exist;
        ReadParticipants(MapParticipants_exist);

        myfile.open(fileName, std::ios::app);
        if ( myfile.is_open() )
        {
            for ( auto oParticipants : MapParticipants)
            {
                //Check for Duplicates (to Write or not)
                if ( MapParticipants_exist.find(oParticipants.first) ==  MapParticipants_exist.end() )
                {
                    auto text = oParticipants.second.encode();
                    myfile << text.c_str();
                }
            }
        }
        myfile.close();
    }
};

int _tmain(int argc, _TCHAR* argv[])
{
    DataReader oReader("File.txt");

    std::map<int, Participants> MapParticipants;

    //Make Some Participants
    Participants p1(1, 50, "TOM");
    Participants p2(2, 40, "TIM");
    Participants p3(3, 80, "JERRY");

    //Add them to map
    MapParticipants[p1.GetId()] = p1;
    MapParticipants[p2.GetId()] = p2;
    MapParticipants[p3.GetId()] = p3;


    oReader.WriteParticipants(MapParticipants);

    oReader.ReadParticipants(MapParticipants);

    //Find and Display
    int id = 2;
    auto it = MapParticipants.find(id);
    if ( it != MapParticipants.end() )
    {
        //Show/Print
        ...
    }

    return 0;
}
Kiran Thilak
  • 443
  • 5
  • 15