【问题标题】:Infinite loop in C++ why?C ++中的无限循环为什么?
【发布时间】:2015-08-02 10:19:57
【问题描述】:

我很抱歉发布超长代码,但是当我运行这段代码时,我看到的只是—— 堆大小:1638652 获取int: 获取int: 获取int: 获取int: 获取int: 堆大小:1638653 它不断循环,堆大小加一。

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

【问题讨论】:

  • 不确定它是否会导致您看到的问题,但 while(!input.eof()) 通常已损坏。
  • 一个经典:`while(!input.eof())`你怎么知道的?你还没有读到任何东西。你怎么知道你打开了文件?
  • @user4581301 那么你们会推荐我做什么?
  • 最好在发送之前将代码最小化....

标签: c++ heap-memory infinite-loop


【解决方案1】:

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

ifstream input(filename); 之后,您不知道文件是否已打开。使用input.is_open() 进行测试可以解决这个问题。

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

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

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

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

if eof() 的问题包含在问题的 cmets 中。基本是在开始阅读之前您不知道文件是否已结束。另外,如果你在一堆读取的中间碰到文件末尾会发生什么?

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

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 >> ...)

【讨论】:

  • 哇,这真的很有帮助,但可以说我不想将它存储在文件中以避免所有这些 eof() 我如何将它保存在 c++ 中而不必打开文件?跨度>
  • @newb12345:如果您更正拼写和标点符号,并拼出“它”是什么,您的问题会更清楚。
  • 在 C++ 中为飓风中心实现一个危机中心(“分类程序”)。您可以使用 STL 或您自己的代码。重复使用的代码必须得到明确承认,并清楚地标记您的贡献。作为当地气象研究所的软件工程师,您将收到包含以下内容的天气报告: 气象站名称 时间和日期 GPS 位置 气压(以百帕或英寸汞柱为单位) 风速(以 km/h、mph 或节为单位) 温度(摄氏或华氏)湿度(百分比)风向
  • 将这些报告添加到适合此问题的数据结构中。根据此数据收集,您将如何: 找到最高风速,然后是较低风速,显示每个数据条目(上面的天气报告) 找到最低气压,然后是较高压力,显示每个数据条目,如上 找到 10最近的报告 查找来自特定气象站的所有报告
  • 这是@Beta 需要做的事情,很抱歉我的拼写和标点错误。
猜你喜欢
  • 1970-01-01
  • 2014-11-05
  • 1970-01-01
  • 2021-07-08
  • 2012-11-12
  • 2010-10-23
  • 1970-01-01
  • 1970-01-01
  • 2020-02-20
相关资源
最近更新 更多