C ++中的无限循环为什么?

时间:2015-05-20 23:25:55

标签: c++ heap infinite-loop

对于发布超长代码我很抱歉,但是当我运行此代码时,我看到的是 - 堆大小:1638652 获得int: 获得int: 获得int: 获得int: 获得int: 堆大小:1638653 并且它继续循环,其中heapsize加1。

#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;
}

1 个答案:

答案 0 :(得分:0)

重要部分。如果您没有阅读其他内容,请阅读:始终检查错误代码并返回值。

ifstream input(filename);之后您不知道文件是否已打开。使用input.is_open()进行的测试已经过去了。

如果文件未打开,则对getline的所有调用都会失败,eof()也会失败。文件未打开,无法读取文件结尾,无法退出循环。即使文件是打开的,如果你没有检查getline的输出,你怎么知道你读了一行?

流的一个有趣的部分是,如果您测试流,它会告诉您它是否处于错误状态,因此您可以编写看起来像

的代码
if (getline(...) && getline(...) && ...)

因此,您不必制作大量if-else-if或大量嵌套ifs。第一次读错了,你出去了。

问题的评论中涵盖了if eof()的问题。基本的是,在你开始阅读之前,你不知道你是否得到了文件的结尾。另外,如果在一堆读取过程中到达文件末尾会发生什么?

所以读一行。如果它很好,请阅读下一行等等......直到完成。

getInt是不必要的。

int val;
input >> val;
如果可以将流解析为int,则

将整数加载到val中。如果不能,输入标记为坏,您可以检查原因。可能是不可解决的。可能是文件结束。

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

就像上面一样,你可以链接说明并获得

if (input >> val >> anotherval >> ...)