ifstream未读取EOF字符

ifstream not reading EOF character

本文关键字:字符 EOF 读取 ifstream      更新时间:2023-10-16

我正在创建一个程序(在C++中),它接受一个ASCII文件,并从每行读取一些值,直到它到达文件的末尾。我使用ifstream来读取文件,并且在使用ifstream.eof()方法时从未遇到过停止文件的问题。然而,这一次,尽管它在我的测试用例中找到了eof字符,但当我分析其他文件时,它是无限循环的,因为它从来没有找到eof字符。这是编码问题,还是我的文件有问题?

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:当我第一次运行循环时,currentfile.good()返回false。。。我在做什么导致它返回?

首先,你不应该那样检查。直到读取失败后eof()才会返回true。但你可以做得更好(更容易)!

使用可在bool上下文中使用的对void*的隐式转换来检查流状态。由于流上的大多数读取操作都返回对流的引用,因此您可以编写一些非常一致的代码,如下所示:

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

基本上,它所做的是说"虽然我可以成功地从currentfile中提取一行,但请执行以下操作",这是你真正想说的;-);

就像我说的,这适用于大多数流操作,所以你可以这样做:

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

编辑:我重写代码的方式如下:

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
}

不要那样做。

EOF并不是你在阅读时唯一会遇到的东西。你可能会遇到一堆错误,所以最好的方法是简单地测试流本身:

while(currentfile)
{
    // read somehow
}

如果你正在阅读行,那么,最简单的方法是:

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

getline的第一次调用触发了ifstream对象上的一个失败位。这就是为什么如果您使用ios::good()检查失败位,则永远不会进入读取循环。我想看看line的值是多少。。。它可能是空的,这意味着你在读取文件时遇到了另一个问题,比如权限问题等。

问题就在这里:

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

试试这个:

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]);
    }   
}