简体   繁体   English

ifstream 不读取 EOF 字符

[英]ifstream not reading EOF character

I am creating a program (In C++) that takes an ASCII file and reads a few values from each line until it reaches the end of the file.我正在创建一个程序(在 C++ 中),它接受一个 ASCII 文件并从每一行读取一些值,直到它到达文件的末尾。 I am using ifstream to read the file, and I have never had problems with it stopping when I use the ifstream.eof() method.我正在使用ifstream来读取文件,当我使用ifstream.eof()方法时,我从来没有遇到过停止它的问题。 This time, however, even though it found the eof character in my test case, when I analyzed my other files, it is infinite looping because it never finds the eof character.然而,这一次,即使它在我的测试用例中找到了 eof 字符,当我分析我的其他文件时,它也是无限循环的,因为它永远找不到 eof 字符。 Is this a coding issue, or an issue with my files?这是编码问题,还是我的文件有问题?

string line = "";
unsigned long pos = 0;
ifstream curfile(input.c_str());
getline(curfile, line);
int linenumber = 0;
cout<<"About to try to read the file"<<endl;
if (!curfile.good())
    cout<<"Bad file read"<<endl;
while (!curfile.eof())
{

    cout<<"Getting line "<<linenumber<<endl;
    linenumber++;
    pos = line.find_first_of(' ');
    line = line.substr(pos+1, line.size()-1);
    pos = line.find_first_of(' ');
    current.push_back(atof(line.substr(0, pos).c_str()));
    for (int i = 0; i<4; i++)
    {
        pos = line.find_first_of(' ');
        line = line.substr(pos+1, line.size()-1);
    }
    pos = line.find_first_of(' ');
    dx.push_back(atof(line.substr(0, pos).c_str()));
    pos = line.find_first_of(' ');
    line = line.substr(pos+1, line.size()-1);
    pos = line.find_first_of(' ');
    dy.push_back(atof(line.substr(0, pos).c_str()));
    getline(curfile, line);
}

EDIT: When I first run the loop, currentfile.good() returns false...what am I doing that causes it to return that?编辑:当我第一次运行循环时, currentfile.good() 返回 false ...我在做什么导致它返回?

First thing is first, you shouldn't check like that.首先,你不应该那样检查。 eof() doesn't return true until after a failed read. eof()直到读取失败后才返回true But you can do better (and easier)!但你可以做得更好(更容易)!

check the stream state with the implicit conversion to void* which can be used in a bool context .检查 stream state 与void*的隐式转换,可以在bool上下文中使用 Since most of the read operations on streams return a reference to the stream, you can write some very consice code like this:由于大多数对流的读取操作都返回对 stream 的引用,因此您可以编写一些非常简洁的代码,如下所示:

std::string line;
while(std::getline(currentfile, line)) {
    // process line
}

Basically what it is doing is saying "while I could successfully extract a line from currentfile , do the following", which is what you really meant to say anyway;-);基本上它所做的是说“虽然我可以成功地从currentfile中提取一行,但请执行以下操作”,这就是您真正想说的;-);

Like I said, this applies to most stream operations, so you can do things like this:就像我说的,这适用于大多数 stream 操作,所以你可以这样做:

int x;
std::string y;
if(std::cin >> x >> y) {
    // successfully read an integer and a string from cin!
}

EDIT : The way I would rewrite your code is like this:编辑:我会重写你的代码的方式是这样的:

string line;
unsigned long pos = 0;
int linenumber = 0;

ifstream curfile(input.c_str());

std::cout << "About to try to read the file" << std::endl;
while (std::getline(curfile, line)) {

    std::cout << "Getting line " << linenumber << std::endl;
    linenumber++;

    // do the rest of the work with line
}

Do not do it like that.不要那样做。

EOF is not the only thing you'll encounter while reading. EOF不是您在阅读时会遇到的唯一事情。 There's a bunch of errors you might get, and so the best is to simply test the stream itself:您可能会遇到很多错误,因此最好的方法是简单地测试 stream 本身:

while(currentfile)
{
    // read somehow
}

If you're reading lines, then, the simplest way is:如果您正在阅读行,那么,最简单的方法是:

std::string line;
while(std::getline(currentfile, line))
{
    // use line
}

Your first call to getline is triggering one of the fail-bits on the ifstream object.您对getline的第一次调用触发了ifstream object 上的一个失败位。 That is why if you do a check for a fail-bit using ios::good() , you never enter your read loop.这就是为什么如果你使用ios::good()检查失败位,你永远不会进入你的读取循环。 I would check to see what the value of line is... it's probably empty, meaning you're having another issue reading your file, like maybe permissions problems, etc.我会检查一下line的值是什么......它可能是空的,这意味着你在读取文件时遇到了另一个问题,比如权限问题等。

The problem is here:问题在这里:

if (!curfile.good())
    cout<<"Bad file read"<<endl;   // OK you print bad.
while (!curfile.eof())             // But the loop is still entered.
                                   // Another reason to **NEVER** to use 
                                   // while (file.eof()) // as bad does not mean eof
                                                         // though eof is bad

Try this:尝试这个:

void readFile(std::istream& str)
{   
    std::string     line;
    while(std::getline(str, line))
    {
        std::stringstream   lineStream(line);
        std::string         ignoreWord;
        int                 number[3];

        lineStream >> ignoreWord   // reads one space seporated word
                   >> number[0]    // reads a number
                   >> ignoreWord >> ignoreWord >> ignoreWords  // reads three words 
                   >> number[1]    // reads a number
                   >> number[2];   // reads a number

        current.push_back(number[0]);
        dx.push_back(number[1]);
        dy.push_back(number[2]);
    }   
}   

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM