-4

Im sorry about posting a super long code, but when I run this code all I see is this- Heap size: 1638652 Getting int: Getting int: Getting int: Getting int: Getting int: Heap size: 1638653 and it keeps going in a loop with the heapsize being incremented by one.

#include <iostream>
#include <fstream>
#include <algorithm>
#include <vector>
#include <exception>

#ifndef WX_REPORT_H
#define WX_REPORT_H


#include <string>
#include <sstream>
using std::string;
using std::stringstream;

typedef struct WX_REPORT

{
    string unitType;
    string stationName;
    string time;
    string gpsLoc;
    int pressure;
    int windSpeed;
    int temperature;
    int humidity;
    int windDirection;

    string toString()
    {
        stringstream str;
        str << stationName << ": " << time << "\t" << gpsLoc << "\n";
        str << pressure << "\n" << windSpeed << "\n" << temperature << "\n";
        str << humidity << "\n" << windDirection;
        return str.str();
    }
}
WXReport;

#endif
/*
 * Reports must be in the following format:
 * M or I // Metric or imperial units
 */
using namespace std;

vector<WXReport*> heap;

bool compTime(const WXReport* a, const WXReport* b) {
    if(a->time < b->time) { // timing
        return false;
    } else {
        return true; // commands to return true
    }
}

void heapAdd(WXReport* wx) {
    heap.push_back(wx);
    push_heap(heap.begin(), heap.end());
}

WXReport* heapPop() { // header popup
    pop_heap(heap.begin(), heap.end());
    WXReport* rep = heap.back();
    heap.pop_back();
    return rep;
}

void getInt(istream &input, int &i) {
    string temp;
    input>>temp;
    cout<<"Getting int: "<<temp<<endl;
    i = atoi(temp.c_str());
}

void readInFile(string filename) {
    ifstream input(filename);
    WXReport *report;
    while(!input.eof()) {
        report = new WXReport();
        getline(input, report->unitType);
        getline(input, report->stationName);
        getline(input, report->time);
        getline(input, report->gpsLoc);
        getInt(input, report->pressure);
        getInt(input, report->windSpeed);
        getInt(input, report->temperature);
        getInt(input, report->humidity);
        getInt(input, report->windDirection);
        heapAdd(report);
        cout<<"Heap size: "<<heap.size()<<endl;
    }
}

int menu() {
    cout<<"\n\nPlease select one: "<<endl;
    cout<<"1) Read in another file"<<endl;
    cout<<"2) Display the fastest wind speed"<<endl;
    cout<<"3) Display weather stations by name"<<endl;
    cout<<"4) Display all weather reports"<<endl;
    cout<<"5) Remove a weather report"<<endl;
    cout<<"6) Write weather reports to file"<<endl;
    cout<<"0) Exit"<<endl;
    int choice;
    cin>>choice;
    return choice;
}

void printAllReports() {
    cout<<"Printing all reports"<<endl;
    for(WXReport* rep: heap) {
        cout<<rep->toString()<<endl;
    }
    cout<<"Done printing reports"<<endl;
}

int main(int argc, char* argv[]) {
    string filename = "report.txt";
    readInFile(filename);

    int choice = menu();
    while(choice != 0) {
        switch(choice) {
            case 1:
                cout<<"What file would you like to read in?"<<endl;
                cin>>filename;
                readInFile(filename);
                break;
            case 2:
                cout<<"Has not been implemented"<<endl;
                break;
            case 3:
                cout<<"Has not been implemented"<<endl;
                break;
            case 4:
                printAllReports();
                break;
            case 5:
                cout<<"Has not been implemented"<<endl;
                break;
            case 6:
                cout<<"Has not been implemented"<<endl;
                break;
            default:
                cout<<"Invalid choice, please try again."<<endl;
        }
        choice = menu();
    }
    cout<<"Thank you!"<<endl;

    return 0;
}
trincot
  • 317,000
  • 35
  • 244
  • 286
newb12345
  • 17
  • 6

1 Answers1

0

Important part. If you read nothing else, read this: Always check the error codes and return values.

After ifstream input(filename); you have no idea if the file opened. Testing with input.is_open() gets past that.

If the file isn't open, all those calls to getline fail as does eof(). File not open, can't read end of file and can't exit loop. Even if the the file is open, if you don't check the output of getline, how do you know you read a line?

One of the fun parts of streams is if you test the stream, it tells you if it is in a bad state, so you can write code that looks like

if (getline(...) && getline(...) && ...)

So you don't have to make a massive block of if-else-if or a sea of nested ifs. First bad read and you are out.

The problem with if eof() is covered in the comments to the question. The basic is you don't know if you got the end of the file until you start reading. Also, what happen if you hit the end of the file in the middle of a bunch of reads?

So read a line. If it's good, read the next line, etc... until done.

getInt isn't necessary.

int val;
input >> val;

loads an integer into val, if the stream can be parsed into an int. If it can't, input is marked bad and you can check why. Could be unparsable. Could be end of file.

int val;
if (input >> val)
{
    //do stuff
} 
else
{
    //no int here. Do other stuff
}

Just like above, you can chain the instructions and get

if (input >> val >> anotherval >> ...)
user4581301
  • 33,082
  • 7
  • 33
  • 54
  • wow this really helped, but lets say i dont want to store it in a file to avoid all this eof() how would i just keep it in c++ and not have to open a file? – newb12345 May 21 '15 at 00:05
  • @newb12345: Your question would be much clearer if you corrected your spelling and punctuation, and spelled out what "it" is. – Beta May 21 '15 at 00:09
  • In C++ implement a crisis center ("triage program") for a hurricane center. You may use STL or your own code. Reused code must be explicitly acknowledged and your contribution clearly marked. As a software engineer for a local meteorological institute, you will be receiving weather reports containing: Weather station name Time and date GPS location Barometric pressure (in hectoPascal or inches of mercury) Wind speed (in km/h, mph, or knots) Temperature (in Celsius or Fahrenheit) Humidity (in percent) Wind direction – newb12345 May 21 '15 at 00:12
  • Add those reports to a data structure that is appropriate for this problem. Based on this data collection how would you: Find the highest wind speed, followed by lesser speeds, showing each data entry (the weather report above) Find the lowest barometric pressure, followed by higher pressure, showing each data entry as above FInd the 10 most recent reports Find all the reports from a particular weather station – newb12345 May 21 '15 at 00:12
  • This is what needs to be done @Beta and sorry for my spelling and punctuation errors. – newb12345 May 21 '15 at 00:13
  • @newb12345 best thing to do is answer a few questions for yourself before writing much more code. First is how do things get in and out? Are you fed data from the keyboard? A file? a network socket? How does the client, assuming an instructor, want the output? Do they want a file? A listing printed to the screen? An Alert E-mail? Once you know how you are getting data in and out, you can start worrying about how you are going to store and organize. If you get hung up at that point, best to ask a new question. – user4581301 May 21 '15 at 00:46
  • @user4581301 we didnt learn file handling yet so it would be displayed to the screen. – newb12345 May 21 '15 at 00:52
  • @newb12345 cin is a stream and operates the same as file stream you're playing with, so most of the stuff I'm talking about, the `getline` and chaining `>>`, can be used to read from the keyboard. For example `if (getline(cin, report->unitType) && getline(cin, report->stationName) && ...)` – user4581301 May 21 '15 at 01:05