I was trying to loop through a list that contains objects. I am reading in data using a weather API and storing each data member as in an object and then storing each object in a list. After I store the whole list, I want to be able to loop through the list and display the objects. I am reading in the data as Json and I am using the casablanca package to do so. All i want to do is be able to loop through my list in the displayFullForcast function in my main.cpp. Here is my list definition:
list<Weather> weather;
Here is my header:
#pragma once
#include<string>
#include<iostream>
#include <list>
using std::list;
using std::string;
//const static int MAX_DAYS = 5;
class Weather
{
public:
Weather();
~Weather();
Weather(double currentTemperature, double maxTemperature,
double minTemperature, string weatherDescription,double humidity, string time);
list<Weather> weather;
private:
string cityState;
double currentTemperature;
double highTemperature;
double lowTemperature;
string weatherDescription;
double humidity;
double highestTemperature;
double lowestTemperature;
string time;
};
Here is my implementation:
#include "Weather.h"
#include <list>
#include <string>
#include <iostream>
using std::cout;
using std::endl;
using std::cin;
Weather::Weather(double currentTemperature, double maxTemperature, double minTemperature,
string weatherDescription, double humidity, string time) :
cityState(cityState), currentTemperature(currentTemperature), highTemperature(highTemperature), lowTemperature(lowTemperature),
weatherDescription(weatherDescription), humidity(humidity), time(time)
{
}
Weather::Weather()
{
cityState = "";
currentTemperature = 0.0;
highTemperature = 0.0;
lowTemperature = 0.0;
weatherDescription = "";
humidity = 0.0;
highestTemperature = 0.0;
lowestTemperature = 0.0;
}
Weather::~Weather()
{
}
and here is my main.cpp
void displayFullForcast()
{
list<Weather>weather;
for (list<Weather>::iterator it = weather.begin(); it != weather.end(); ++it)
{
cout << *it << endl;
}
}
void displayTodayForcast()
{
list<Weather>weather;
}
void displayLowHigh()
{
list<Weather>weather;
}
void displayHumidity()
{
list<Weather>weather;
}
void displayMenu()
{
int choice = 0;
cout << "What option would you like to see:\n"
<< "(1) Forcast for 5 days\n"
<< "(2) Forcast for Today\n"
<< "(3) The Lowest and Highest Temperature\n"
<< "(4) Humidity for Today\n" << endl;
cin >> choice;
switch (choice)
{
case 1: displayFullForcast();
break;
case 2: displayTodayForcast();
break;
case 3: displayLowHigh();
break;
case 4: displayHumidity();
break;
}
}
void executeWeatherQuery()
{
http_client client(U("http://api.openweathermap.org"));
uri_builder builder(U("/data/2.5/forecast"));
builder.append_query(U("q"), U("Searcy,AR"));
builder.append_query(U("appid"), U("5ee41aef99a6e283abcdd5a04d89ae67"));
builder.append_query(U("units"), U("imperial"));
builder.append_query(U("mode"), U("json"));
http_response response = client.request(methods::GET, builder.to_string()).get();
web::json::value forecastJson = response.extract_json(true).get();
web::json::value forecastListJson = forecastJson.at(U("list"));
if (forecastListJson.is_array())
{
for (size_t i = 0; i < forecastListJson.size(); i++)
{
web::json::value forecastDayJson = forecastListJson[i];
web::json::value mainJson = forecastDayJson.at(U("main"));
web::json::value currentTemperatureJson = mainJson.at(U("temp"));
double currentTemperature = 0;
if (!currentTemperatureJson.is_null())
{
currentTemperature = currentTemperatureJson.as_double();
}
cout << "Current Temperature " << currentTemperature << endl;
web::json::value weatherJson = forecastDayJson.at(U("weather"))[0];
web::json::value mainWeatherJson = weatherJson.at(U("main"));
string weatherDescription = "";
if (!mainWeatherJson.is_null())
{
weatherDescription = conversions::to_utf8string(mainWeatherJson.as_string());
}
cout << "Weather Description " << conversions::to_utf8string(weatherDescription) << endl;
web::json::value MainJson = forecastDayJson.at(U("main"));
web::json::value minTemperatureJson = MainJson.at(U("temp"));
double minTemperature = 0;
if (!minTemperatureJson.is_null())
{
minTemperature = minTemperatureJson.as_double();
}
cout << "Min Temp: " << minTemperature << endl;
web::json::value MainMaxJson = forecastDayJson.at(U("main"));
web::json::value maxTemperatureJson = MainMaxJson.at(U("temp"));
double maxTemperature = 0;
if (!maxTemperatureJson.is_null())
{
maxTemperature = maxTemperatureJson.as_double();
}
cout << "Max " << maxTemperature << endl;
web::json::value MainHumidityJson = forecastDayJson.at(U("main"));
web::json::value humidityJson = MainHumidityJson.at(U("humidity"));
double humidity = 0;
if (!MainHumidityJson.is_null())
{
humidity = humidityJson.as_double();
}
cout << "Humidity: " << humidity << endl;
web::json::value MainTimeJson = forecastDayJson.at(U("dt_txt"));
string time = "";
if (!MainTimeJson.is_null())
{
time = conversions::to_utf8string(MainTimeJson.as_string());
//time = localtime(time);
}
cout << "Time" << time << endl;
Weather WeatherForcast(currentTemperature, maxTemperature, minTemperature,
weatherDescription, humidity, time);
list<Weather>weather;
weather.push_back(WeatherForcast);
}
}
}
void main()
{
/*string location;
cout << "Please enter a city and a State (Example: Searcy,AR)" << endl;
cin >> location;*/
executeWeatherQuery();
displayMenu();
}
** I am receiving this error still on the line cout << *it << endl; Error: No operator "<<" matches these operands. operands types are std::ofstream and Weather.
I don't have that specific weather API package installed, but from your code, it looks like you just have a scoping problem.
In your executeWeatherQuery
, you declare a list<Weather> weather;
and then do weather.push_back(WeatherForcast);
; that weather
object is local to the executeWeatherQuery
function only, so as soon as that function ends, that weather
object goes out of scope and the data within it is no longer valid. Further, your other functions that are to display
the list, all create their own local list<Weather> weather;
.
Instead, try having a global list<Weather> weather
that you operate on. Here's your main code with a static local (global) weather object:
static list<Weather> weather;
void displayFullForcast()
{
for (list<Weather>::iterator it = weather.begin(); it != weather.end(); ++it)
{
cout << *it << endl;
}
}
void displayTodayForcast()
{
}
void displayLowHigh()
{
}
void displayHumidity()
{
}
void displayMenu()
{
int choice = 0;
cout << "What option would you like to see:\n"
<< "(1) Forcast for 5 days\n"
<< "(2) Forcast for Today\n"
<< "(3) The Lowest and Highest Temperature\n"
<< "(4) Humidity for Today\n" << endl;
cin >> choice;
switch (choice)
{
case 1: displayFullForcast();
break;
case 2: displayTodayForcast();
break;
case 3: displayLowHigh();
break;
case 4: displayHumidity();
break;
}
}
void executeWeatherQuery()
{
http_client client(U("http://api.openweathermap.org"));
uri_builder builder(U("/data/2.5/forecast"));
builder.append_query(U("q"), U("Searcy,AR"));
builder.append_query(U("appid"), U("5ee41aef99a6e283abcdd5a04d89ae67"));
builder.append_query(U("units"), U("imperial"));
builder.append_query(U("mode"), U("json"));
http_response response = client.request(methods::GET, builder.to_string()).get();
web::json::value forecastJson = response.extract_json(true).get();
web::json::value forecastListJson = forecastJson.at(U("list"));
if (forecastListJson.is_array())
{
for (size_t i = 0; i < forecastListJson.size(); i++)
{
web::json::value forecastDayJson = forecastListJson[i];
web::json::value mainJson = forecastDayJson.at(U("main"));
web::json::value currentTemperatureJson = mainJson.at(U("temp"));
double currentTemperature = 0;
if (!currentTemperatureJson.is_null())
{
currentTemperature = currentTemperatureJson.as_double();
}
cout << "Current Temperature " << currentTemperature << endl;
web::json::value weatherJson = forecastDayJson.at(U("weather"))[0];
web::json::value mainWeatherJson = weatherJson.at(U("main"));
string weatherDescription = "";
if (!mainWeatherJson.is_null())
{
weatherDescription = conversions::to_utf8string(mainWeatherJson.as_string());
}
cout << "Weather Description " << conversions::to_utf8string(weatherDescription) << endl;
web::json::value MainJson = forecastDayJson.at(U("main"));
web::json::value minTemperatureJson = MainJson.at(U("temp"));
double minTemperature = 0;
if (!minTemperatureJson.is_null())
{
minTemperature = minTemperatureJson.as_double();
}
cout << "Min Temp: " << minTemperature << endl;
web::json::value MainMaxJson = forecastDayJson.at(U("main"));
web::json::value maxTemperatureJson = MainMaxJson.at(U("temp"));
double maxTemperature = 0;
if (!maxTemperatureJson.is_null())
{
maxTemperature = maxTemperatureJson.as_double();
}
cout << "Max " << maxTemperature << endl;
web::json::value MainHumidityJson = forecastDayJson.at(U("main"));
web::json::value humidityJson = MainHumidityJson.at(U("humidity"));
double humidity = 0;
if (!MainHumidityJson.is_null())
{
humidity = humidityJson.as_double();
}
cout << "Humidity: " << humidity << endl;
web::json::value MainTimeJson = forecastDayJson.at(U("dt_txt"));
string time = "";
if (!MainTimeJson.is_null())
{
time = conversions::to_utf8string(MainTimeJson.as_string());
//time = localtime(time);
}
cout << "Time" << time << endl;
Weather WeatherForcast(currentTemperature, maxTemperature, minTemperature,
weatherDescription, humidity, time);
weather.push_back(WeatherForcast);
}
}
}
void main()
{
/*string location;
cout << "Please enter a city and a State (Example: Searcy,AR)" << endl;
cin >> location;*/
executeWeatherQuery();
displayMenu();
}
Note how there's only one weather
object that's operated on within the scope of the file, instead of one weather
object per function.
Hope that can help.