//HI,need help to extract info from text file  and display.
//Here is my text file called Report.txt 
01 09 2014 john   3.4 12.5 9.5
02 09 2014 freddy 3.4 12.5 9.5
03 09 2014 conor  3.4 12.5 9.5
04 09 2014 mike   3.4 12.5 9.5
05 09 2014 john   3.4 12.5 9.5
06 09 2014 john   3.4 12.5 9.5
07 09 2014 mike   3.4 12.5 9.5
08 09 2014 freddy 3.4 12.5 9.5
09 09 2014 conor  3.4 12.5 9.5
10 09 2014 conor  3.4 12.5 9.5
11 09 2014 john   3.4 12.5 9.5
12 09 2014 mike   3.4 12.5 9.5
13 09 2014 john   3.4 12.5 9.5
14 09 2014 john   3.4 12.5 9.5
15 09 2014 mike   3.4 12.5 9.5
16 09 2014 conor  3.4 12.5 9.5
17 09 2014 conor  3.4 12.5 9.5
18 09 2014 fredyy 3.4 12.5 9.5
19 09 2014 freddy 3.4 12.5 9.5
20 09 2014 mike   3.4 12.5 9.5
21 09 2014 conor  3.4 12.5 9.5
22 09 2014 conor  3.4 12.5 9.5
23 09 2014 mnike  3.4 12.5 9.5
24 09 2014 mike   3.4 12.5 9.5
25 09 2014 john   3.4 12.5 9.5
26 09 2014 conor  3.4 12.5 9.5
27 09 2014 freddy 3.4 12.5 9.5
28 09 2014 freddy 3.4 12.5 9.5
29 09 2014 mike   3.4 12.5 9.5
30 09 2014 john   3.4 12.5 9.5


So it,s a date,name,hours of sunshine (double)
    rainfall in millimeters (double)
    midday temperature in degrees (double)
 Here is the code:
 #include "stdafx.h"
#include<iostream>
#include<fstream>
#include<string>
#include<vector>



using namespace std;
struct DATE{
    int day;
    int month;
    int year;


   };

struct onDutyRecords{
    string name;
    double sunshine;
    double rainfall;
    double midTemp;
    DATE date;

             };






int ShowMenu(void);

void ListDaysOnDutyOfMet(void);
void ListAllTheWetDays(void);
void ListDaysOnDutyOfMet(void);
void ListAllTheSunnyDays(void);
void ListAverageOfTwoDays(void);
void ListHotestDayByMiddayTemp(void);
void ListDaysWithShortestSunshine(void);
void Exit(void);
bool quitFlag = false;
void LoadFile(void);






int _tmain(int argc, _TCHAR* argv[])
{


    int option;
    do
    { 
        option = ShowMenu();
        switch (option)
        {
        case 0:
            ListDaysOnDutyOfMet();
            break;
        case 1:
            ListAllTheWetDays();
            break;

        case 2:
            ListAllTheSunnyDays();
            break;
        case 3:
            ListAverageOfTwoDays();
            break;
        case 4:
            ListHotestDayByMiddayTemp();
            break;
        case 5:
            ListDaysWithShortestSunshine();
            break;

        case 6:
            Exit();
            break;

        default:
            cout << "invalid option\n";
        }
    } while (!quitFlag);





    return 0;
}


int ShowMenu(void)
    {
        int option;
        cout << "\n\n\n";
        cout << "\t0. Do Days On Duty Of Meteorologist\n";
        cout << "\t1. Display All The Wet Days\n";
        cout << "\t2. All The Sunny Days\n";
        cout << "\t3. Average Of Two Days\n";
        cout << "\t4. Hotest Day By Midday Temp\n";
        cout << "\t5.\tDays With Shortest Sunshine\n";
        cout << "\t6. Exit\n";
        cout << "\t\tEnter option : ";
        cin >> option;
        cout << endl << endl;
        return option;
    }



void ListDaysOnDutyOfMet(void)
{
    cout << "Not impl";

}

void ListAllTheWetDays(void)
{
    cout << "Not impl";
}

void ListAllTheSunnyDays(void)
{
    cout << "Not impl";

}
void ListAverageOfTwoDays(void)
{
    cout << "Not impl";
}
void ListHotestDayByMiddayTemp(void)
{
    cout << "Not impl";
}

void ListDaysWithShortestSunshine(void)
{

    cout << "Not impl";
}
void Exit(void)
{
     quitFlag = true;

}
void LoadFile(void)
{
    ifstream infile("Report.txt");
    if (!infile)
    {
        cout << "Database file does not exist.";


    }
    else
    {
        struct DATE Date;
       infile >> Date.day >> Date.month >> Date.year;

        struct onDutyRecords record;
        infile >> record.name >> record.sunshine >> record.rainfall >> record.midTemp;


    }



}

As you can see at the end need somehow to merge this structs and display,so i could use other functions.

Edited 2 Years Ago by aluhnev: mistake

Your first step would to use the date property of the onDutyRecords instead of a separate DATE object. This will put the data for one line in one struct object.

Something like this should work:

    struct onDutyRecords record;
    infile >> record.date.day >> record.date.month >> record.date.year;      
    infile >> record.name >> record.sunshine >> record.rainfall >> record.midTemp;

Now your data is ready to store and/or display.

Edited 2 Years Ago by tinstaafl

Sorry for asking stupid queston,ijust strarting on structs.How will output/dispaly this struct.i have "cout "after inflie.But even with the function call io the main loadFile(),nothing is displayed.

I see nothing in your code about where you're calling the LoadFile function or displaying the data.

You can display the data with cout, something like this:

    cout << record.date.day << "/" << record.date.month << "/" << record.date.year << " - ";      
    cout << record.name << " " << record.sunshine << " " << record.rainfall << " " << record.midTemp << "\n";
/////////////////////////////////////////////////////////
Why is on line 141 ,the  << operator after 'found' not recognized?

In the function ListDaysOnDuty
//////////////////////////////////////////////////////////////
#include "stdafx.h"
#include<iostream>
#include<fstream>
#include<string>
#include<vector>
#include<algorithm>





using namespace std;
struct DATE{
    int day;
    int month;
    int year;


   };

struct onDutyRecords{
    string name;
    double sunshine;
    double rainfall;
    double midTemp;
    DATE date;

             };

vector<onDutyRecords>records;





int ShowMenu(void);

void ListDaysOnDutyOfMet(void);
void ListAllTheWetDays(void);
void ListDaysOnDutyOfMet(void);
void ListAllTheSunnyDays(void);
void ListAverageOfTwoDays(void);
void ListHotestDayByMiddayTemp(void);
void ListDaysWithShortestSunshine(void);
void Exit(void);
bool quitFlag = false;
void LoadFile(void);
void Display(void);







int _tmain(int argc, _TCHAR* argv[])
{


    int option;
    do
    { 
        option = ShowMenu();
        switch (option)
        {
        case 8 :
            Display();

        case 0:
            ListDaysOnDutyOfMet();
            break;
        case 1:
            ListAllTheWetDays();
            break;

        case 2:
            ListAllTheSunnyDays();
            break;
        case 3:
            ListAverageOfTwoDays();
            break;
        case 4:
            ListHotestDayByMiddayTemp();
            break;
        case 5:
            ListDaysWithShortestSunshine();
            break;

        case 6:
            Exit();
            break;

        default:
            cout << "invalid option\n";
        }
    } while (!quitFlag);





    return 0;
}


int ShowMenu(void)
    {
        int option;
        cout << "\n\n\n";
        cout << "\t8.\t   Display\n";
        cout << "\t0. Do Days On Duty Of Meteorologist\n";
        cout << "\t1. Display All The Wet Days\n";
        cout << "\t2. All The Sunny Days\n";
        cout << "\t3. Average Of Two Days\n";
        cout << "\t4. Hotest Day By Midday Temp\n";
        cout << "\t5.\tDays With Shortest Sunshine\n";
        cout << "\t6. Exit\n";
        cout << "\t\tEnter option : ";
        cin >> option;
        cout << endl << endl;
        return option;
    }



void ListDaysOnDutyOfMet(void)
{

    string name;
    cout << "Enter the name of the person on duty:";
    cin >> name;
    vector<onDutyRecords> :: iterator it; 
    it = find(records.begin(), records.end(), name);
    if (it!= records.end())
    {
        cout << "found" <<  *it << endl;
    }



}

void ListAllTheWetDays(void)
{
    cout << "Not impl";
}

void ListAllTheSunnyDays(void)
{
    cout << "Not impl";

}
void ListAverageOfTwoDays(void)
{
    cout << "Not impl";
}
void ListHotestDayByMiddayTemp(void)
{
    cout << "Not impl";
}

void ListDaysWithShortestSunshine(void)
{

    cout << "Not impl";
}
void Exit(void)
{
     quitFlag = true;

}
void LoadFile(void)
{
    ifstream infile("Report.txt");
    while (!infile.eof())
    {
        struct onDutyRecords record;
        infile >> record.date.day >> record.date.month >> record.date.year;
        infile >> record.name >> record.sunshine >> record.rainfall >> record.midTemp;

        cout <<  setw(20) << right << record.date.day << " " << record.date.month << " " << record.date.year << " "
            << setw(10) << left << record.name << " " << record.sunshine << " " << record.rainfall << " " << record.midTemp << endl;

        records.push_back(record);


    }






}

void Display(void)
{
    for (int i = 0; i < records.size(); i++)
    {
        records[i];

    }


}

Edited 2 Years Ago by aluhnev

First off, your code doesn't call LoadFile(), so the vector doesn't get populated and there is nothing to find.

Secondly, using find, you're trying to compare a string(name) with an onDutyRecords object, which will never find a match. You probably need to use the find_if method with a predicate to compare the name property of onDutyRecords member of the vector.

Thirdly, you're trying to send a custom object through a stream(cout << "found" << *it << endl;), which will throw an error since the stream won't know how to format the data. Implementing a ToString() method in your struct will help with this(cout << "found" << (*it).ToString() << endl;)

Here's some modified code for you to consider:

#include "stdafx.h"
#include<iostream>
#include <iomanip>
#include<fstream>
#include<string>
#include <sstream>
#include<vector>
#include<algorithm>

using namespace std;

struct DATE{
    int day;
    int month;
    int year;
};
struct onDutyRecords{
    string name;
    double sunshine;
    double rainfall;
    double midTemp;
    DATE date;
    string ToString()
    {
        stringstream ss("");
        ss << setw(20) << right << date.day << " " << date.month << " " << date.year << " "
            << setw(10) << left << name << " " << sunshine << " " << rainfall << " " << midTemp << '\n';
        return ss.str();
    }
};
vector<onDutyRecords>records;
int ShowMenu(void);
void ListDaysOnDutyOfMet(void);
void ListAllTheWetDays(void);
void ListDaysOnDutyOfMet(void);
void ListAllTheSunnyDays(void);
void ListAverageOfTwoDays(void);
void ListHotestDayByMiddayTemp(void);
void ListDaysWithShortestSunshine(void);
void Exit(void);
bool quitFlag = false;
void LoadFile(void);
void Display(void);
int _tmain(int argc, _TCHAR* argv[])
{
    LoadFile();
    int option;
    do
    {
        option = ShowMenu();
        switch (option)
        {
        case 8:
            Display();
            break;
        case 0:
            ListDaysOnDutyOfMet();
            break;
        case 1:
            ListAllTheWetDays();
            break;
        case 2:
            ListAllTheSunnyDays();
            break;
        case 3:
            ListAverageOfTwoDays();
            break;
        case 4:
            ListHotestDayByMiddayTemp();
            break;
        case 5:
            ListDaysWithShortestSunshine();
            break;
        case 6:
            Exit();
            break;
        default:
            cout << "invalid option\n";
        }
    } while (!quitFlag);
    return 0;
}
int ShowMenu(void)
{
    int option;
    cout << "\n\n\n";
    cout << "\t8.\t   Display\n";
    cout << "\t0. Do Days On Duty Of Meteorologist\n";
    cout << "\t1. Display All The Wet Days\n";
    cout << "\t2. All The Sunny Days\n";
    cout << "\t3. Average Of Two Days\n";
    cout << "\t4. Hotest Day By Midday Temp\n";
    cout << "\t5.\tDays With Shortest Sunshine\n";
    cout << "\t6. Exit\n";
    cout << "\t\tEnter option : ";
    cin >> option;
    cout << endl << endl;
    return option;
}
void ListDaysOnDutyOfMet(void)
{
    string name;
    cout << "Enter the name of the person on duty:";
    cin >> name;
    vector<onDutyRecords> ::iterator it;
    it = find_if(records.begin(), records.end(), [&name](onDutyRecords odr){return odr.name == name; });
    if (it != records.end())
    {
        cout << "found" << (*it).ToString() << endl;
    }
}
void ListAllTheWetDays(void)
{
    cout << "Not impl";
}
void ListAllTheSunnyDays(void)
{
    cout << "Not impl";
}
void ListAverageOfTwoDays(void)
{
    cout << "Not impl";
}
void ListHotestDayByMiddayTemp(void)
{
    cout << "Not impl";
}
void ListDaysWithShortestSunshine(void)
{
    cout << "Not impl";
}
void Exit(void)
{
    quitFlag = true;
}
void LoadFile(void)
{
    ifstream infile("Report.txt");
    struct onDutyRecords record;
    while (infile >> record.date.day >> record.date.month >> record.date.year)
    {
        infile >> record.name >> record.sunshine >> record.rainfall >> record.midTemp;
        cout << record.ToString();
        records.push_back(record);
    }
}
void Display()
{
    for (int i = 0; i < records.size(); i++)
    {
        cout << records[i].ToString() << '\n';
    }
}

Edited 2 Years Ago by tinstaafl

The compiler doesn't recognize ToString() method, i have all headers included,it says :#error vccorlib.h can only be used with /ZW.
ToString is underlined.Is it because i use 2013 version?

Edited 2 Years Ago by aluhnev

Did you add the ToString method to your struct, as per the code I showed you?

This code was compiled and tested of VS2013. It should work as is, in its entirety.

Edited 2 Years Ago by tinstaafl

Yes,i did included in struct ToString,but still get an error:
c:\program files\microsoft visual studio 12.0\vc\include\vccorlib.h(29): fatal error C1189: #error :  vccorlib.h can only be used with /ZW

Sounds like you need to enable Consume Windows Runtime Extension. This is in the Properties. Expand C/C++ and select All Options. Look for that option and change it to yes and see if that helps.

If you don't need the .net librairies for your project, you're probably better off starting a new Win32 Console project and in the Application Settings form, select Console Application and uncheck everything else. You should be able to copy all your code, except for #include "stdafx.h", into the new project.

Thanks,will try this. One more question do i need to keep vector global or it is better to put it in main and pass vector to functions,will it make any difference from point of consuming memory?

Memory wise it shouldn't matter. However in terms of keeping track of what values the vector holds, it's much easier to maintain if you pass the vector to each function that uses it.

///////////////////////////////////////////////////////

Struct defined in seperate header Structs.h
//////////////////////////////////////////////
#ifndef STRUCTS_H
#define STRUCTS_H

#pragma once
#include <string>

using namespace std;

struct Date
{
    int Day;
    int Month;
    int Year;

    // overloads for easy comparison of Dates
    bool operator>=(const Date& date2) const;
    bool operator<=(const Date& date2) const;
    bool operator==(const Date& date2) const;
};

struct Record
{
    Date date;
    string Name;        //meteorologist name

    double sunHours;    //hours of sunshine
    double rainLevel;   //rainfall in mm
    double temp;        //midday temperature ind degrees celsius
};

enum Options            //menu options
{
    Load, ListOnDuty, ListWet, ListSunny, RainfallAverage, Hottest, ShortestSun, Exit
};


#endif

///////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Structs.h"

using namespace std;


// Callbacks
void DoLoadDatabase(vector<Record>& records, ifstream& inFile);
void DoListWorkerDays(vector<Record>& records);
void DoListWetDays(vector<Record>& records);
void DoListSunnyDays(vector<Record>& records);
void DoListRainfallAverage(vector<Record>& records);
void DoFindHottestDay(vector<Record>& records);
void DoFindShortestSun(vector<Record>& records);
void DoExit(void);

// Helpers
int ShowMenu(void);
void ShowRecord( const Record& record );

//globals
bool Quit = false;




int _tmain(int argc, _TCHAR* argv[])
{
    vector<Record> records;              //main array of records:

    int option;                         //int holding selected option:

    ifstream inFile("records_db.txt");  //open database file

    while( !Quit )
    {
        option = ShowMenu();

        switch(option)
        {
        case Load:
            DoLoadDatabase(records, inFile);
            break;
        case ListOnDuty:
            DoListWorkerDays(records);
            break;
        case ListWet:
            DoListWetDays(records);
            break;
        case ListSunny:
            DoListSunnyDays(records);
            break;
        case RainfallAverage:
            DoListRainfallAverage(records);
            break;
        case Hottest:
            DoFindHottestDay(records);
            break;
        case ShortestSun:
            DoFindShortestSun(records);
            break;
        case Exit:
            DoExit();
            break;
        }
    }


    return 0;
}



void DoLoadDatabase(vector<Record>& records, ifstream& inFile)
{
    Date date;          // create empty date
    Record record;      // create empty record

    while( inFile >>record.date.Day  >> record.date.Month >> record.date.Year)
    {

        inFile >> record.Name >> record.sunHours >> record.rainLevel >> record.temp;        
        records.push_back(record);
    }               

}

void DoListWorkerDays(vector<Record>& records)
{
    cout << "Enter meteorologist's name:";

    string name;
    cin >> name;
    cin.ignore();


    bool found = false;         

    for(auto record : records)
    {
        if( record.Name == name)
        {
            if( !found )        
                found = true;

            ShowRecord( record );
        }
    }

    if( !found )
        cout << "No records with name " << name << " found." << endl;
}

void DoListWetDays(vector<Record>& records)
{
    cout << "Days with rainfall level greater or equal to 4mm:" << endl;

    for(auto record : records)
    {
        if( record.rainLevel >= 4. )
            ShowRecord( record );
    }
}

void DoListSunnyDays(vector<Record>& records)
{
    cout << "Days with 5 or more sunny hours:" << endl;

    for( auto record : records )
    {
        if( record.sunHours >= 5 )
            ShowRecord( record );
    }
}

void DoListRainfallAverage(vector<Record>& records)
{
    cout << "Find average rainfall between two dates.\n" << endl;
    cout << "Enter the first date (year, month, day): ";

    Date date1;
    cin >> date1.Year >> date1.Month >> date1.Day;
    cin.ignore();

    cout << "\nEnter the second date (year, month, day): ";

    Date date2;
    cin >> date2.Year >> date2.Month >> date2.Day;
    cin.ignore();

    double totalRainMm = 0;
    int dayCount = 0;

    // Check whether dates entered are in a list
    bool found1 = false;
    bool found2 = false;

    for(auto& record : records)
    {
        if(record.date == date1 )
            found1 = true;

        if( record.date == date2)
            found2 = true;
    }

    if( !found1 )
    {
        cout << "\nFirst date is not in a database." << endl;
        return;
    }
    if( !found2 )
    {
        cout << "\nSecond date is not in a database." << endl;
        return;
    }

    for(auto& record : records )
    {
        if( record.date >= date1 && record.date <= date2 )
        {
            totalRainMm += record.rainLevel;
            ++dayCount;
        }
    }

    double averageRainfall = totalRainMm / dayCount;

    cout << "Average Rainfall in the stated period is " << averageRainfall << "mm." << endl;

}

void DoFindHottestDay(vector<Record>& records)
{
    cout << "Details of the hottest day(s):" << endl;

    double hottest = 0;

    // find hottest temp
    for(auto& record : records)
    {
        if( hottest < record.temp )
            hottest = record.temp;
    }

    // display details of hottest days
    for(auto& record : records )
    {
        if( record.temp == hottest )
            ShowRecord( record );
    }
}

void DoFindShortestSun(vector<Record>& records)
{
    cout << "Details of day(s) with shortest sunshine: " << endl;

    double shortestSun = records[0].sunHours;

    for( auto& record : records )
    {
        if( shortestSun > record.sunHours )
            shortestSun = record.sunHours;
    }

    for(auto& record: records )
    {
        if( record.sunHours == shortestSun )
            ShowRecord( record );
    }
}

void DoExit(void)
{
    Quit = true;
}

int ShowMenu(void)
{

    cout << "\t\t" << endl;
    cout << "\t\tOptions:\n";

    cout << "\t\t0. Load Database File" << endl;
    cout << "\t\t1. Find Dates For Given Meteorologist." << endl;
    cout << "\t\t2. Find All Wet Days" << endl;
    cout << "\t\t3. Find All Sunny Days." << endl;
    cout << "\t\t4. Find Average Rainfall Between Two Dates" << endl;
    cout << "\t\t5. Find The Hottest Day (based on midday temperature)" << endl;
    cout << "\t\t6. Find Shortest Sunshine Day" << endl;
    cout << "\t\t7. Exit." << endl;

    int option;
    cout << "Enter Option: ";
    cin >> option;
    cin.ignore();       

    return option;

}

void ShowRecord( const Record& record )
{
    cout << record.date.Day << "\t" << record.date.Month << "\t" << record.date.Year << "\t"
        << record.Name << "\t" << record.sunHours << "\t" << record.rainLevel << "\t" << record.temp << endl;
}



///////////////////////////////////////////

Can any modification  be done to simplify it or code is ok.?


//////////////////////////////////////

Edited 2 Years Ago by aluhnev

Nothing major jumps out at me. If your question is answered, please remember to mark this solved. Thanks.

This question has already been answered. Start a new discussion instead.