【问题标题】:Boolean function doesn't read all the input from a text file布尔函数不会从文本文件中读取所有输入
【发布时间】:2012-08-26 19:19:54
【问题描述】:

您好,我正在处理一个学校项目,但我在使用特定功能时遇到了困难。 我已经研究了一段时间,我将不胜感激任何类型的输入。

我们必须使用这个函数:

bool movieLibrary::readMovieInfo(ifstream& inFile)
{
    inFile>>rank>>year>>votes>>nationality;
    getline(inFile,nameMovie);

    if (rank < 1)
        return false;
    else
        return true;
}

我的主要功能总是给出错误的输出:

#include "movieLibrary.h"
#include <iostream>
#include <fstream>

using namespace std;

int main()
{
movieLibrary myMovie[5];
ifstream inFile("myMovieLibrary.txt");

int i =0;

//my issue is here
while (myMovie[i].readMovieInfo(inFile))
{       
    i++;
    myMovie[i].readMovieInfo(inFile);   
}

for (int i=0;i<5;++i)
{
    myMovie[i].printMovieInfo("printList.txt");
}

return 0;
}

这是输出,应该与输入相同,但这是我得到的:

3 2000 24446 b  Snatch
2 2008 1902 b  RocknRolla
5 2007 25510 a  American Gangster
-1 -858993460 -858993460 Ì 
-858993460 -858993460 -858993460 Ì 

这是输入:myMovieLibrary.txt

3 2000 24446 b Snatch
2 2004 2872 b Layer Cake
2 2008 1902 b RocknRolla
4 1999 7661 b Lock,Stock and Two Smoking Barrels
5 2007 25510 a American Gangster
-1
rank year votes Nationality (b:british; a:american) name

这是 MovieLibrary 规范文件:

#include <string>

class movieLibrary
{
public:
movieLibrary();
~movieLibrary();

//void readMovieInfo(std::ifstream&);
bool readMovieInfo(std::ifstream&);
void printMovieInfo(char*);
char getNationality();
int getRank();
bool operator>=(movieLibrary) const;
bool operator<(movieLibrary) const;

private:
int rank; //rank I gave to the movie in my library
int year; //year the movie came out
int votes; //the number of votes that yahoo users gave the movie
std::string nameMovie; //the name of the movie
char nationality; //nationality of movie: b for british and a for american
};

MovieLibrary 的实现类:

#include "movieLibrary.h"
#include <fstream>
#include <string>

using namespace std; // here you can use that.


movieLibrary::movieLibrary()
{
}

movieLibrary::~movieLibrary()
{
}

bool movieLibrary::readMovieInfo(ifstream& inFile)
{
    inFile>>rank>>year>>votes>>nationality;
    getline(inFile,nameMovie);

    if (rank < 1)
        return false;
    else
        return true;
}

void movieLibrary::printMovieInfo(char* outFileName)
{
std::ofstream outFile;
if(!outFile.is_open()) 
    outFile.open(outFileName, std::ios::app);
outFile<<rank<<" "<<year<<" "<<votes<<" "<<nationality<<" "<<nameMovie<<std::endl;

}
int movieLibrary::getRank()
{
return rank;
}

char movieLibrary::getNationality()
{
return nationality;
}

【问题讨论】:

    标签: c++ class fstream


    【解决方案1】:
    while (myMovie[i].readMovieInfo(inFile))
    {       
        i++;
        myMovie[i].readMovieInfo(inFile);   
    }
    

    这段代码执行这个:

    myMovie[0].readMovieInfo(inFile); // loads Snatch into [0]
    myMovie[1].readMovieInfo(inFile); // loads Layer Cake into [1]
    myMovie[1].readMovieInfo(inFile); // loads RocknRolla into [1] 
    myMovie[2].readMovieInfo(inFile); // loads Lock,Stock.. into [2]
    myMovie[2].readMovieInfo(inFile); // loads Armerican Gangster into [2] 
    // until it returns false
    

    readMoveInfo 的这种重复调用是导致您的程序覆盖每 2 行的原因,例如myMovie[1] 将首先包含“Layer Cake”,但在while() 中执行该函数后将被“RocknRolla”覆盖。正如已经指出的另一个答案,最简单的解决方法就是删除 readMovieInfo 的第二次调用,留下这个:

    while (myMovie[i].readMovieInfo(inFile)) i++;
    

    【讨论】:

    • MS VS2008 给我一个调试错误:运行时检查失败 #2 当我使用这一行时:while (myMovie[i].readMovieInfo(inFile)) i++;
    • 它说:围绕变量“myMovie”的堆栈已损坏
    • 好吧,确实,你还需要检查 i while(i < 5 && myMovie[i].readMovieInfo(inFile)) i++; 请注意,这只会读取 5 部电影,但你正在以这种方式初始化它:movieLibrary myMovie[5];。您可能想使用具有动态大小的东西。
    【解决方案2】:

    由于您在循环条件中调用readMovieInfo以及在循环主体中,您将为除 0 之外的每个索引调用两次。

    由于您在每次迭代的第二次调用之前递增i,因此您将用第三个元素覆盖第二个元素,用第五个覆盖第四个元素,依此类推:您将丢失输入文件中的所有其他电影。这反映在您的输出中:第二和第四部电影消失了。

    请记住,每次迭代都会测试您的循环条件,因此您需要注意条件测试的任何副作用。

    您可以通过删除对readMovieInfo 的一个或其他调用来解决此问题(作为练习,尝试两种方式进行),但我更希望看到您在不调用readMovieInfo 的情况下编写while 条件;完成此操作后,请考虑 do/while 循环是否更好,以及为什么。

    最后,请注意,您还应该检查您读取的元素是否超过了数组可以容纳的数量。当您这样做时,您的循环条件会变得更加复杂。

    【讨论】:

    • while (true) { if (!myMovie[i++].readMovieInfo(inFile)) break; }
    • @user1561949 干得好。但是不使用break 怎么办?您的循环将不那么简短,但可能会读得更清楚。
    • 我在不使用中断的情况下绘制空白。你有提示吗?
    • 您可以使用单独的bool 变量。
    • 当然,您可以将其视为循环继续标志
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-20
    • 1970-01-01
    • 2017-11-18
    • 1970-01-01
    • 2020-06-18
    • 1970-01-01
    相关资源
    最近更新 更多