到达文件结束后从文件中读取



我有一个名为readNextString(ifstream &file , char* &pBuffer)的函数,它从文件中提取下一个字符串,直到达到',''n',删除字符串开头和末尾的空白,将其余部分保存在pBuffer中,如果一切正常工作则返回true -否则为false。在到达文件末尾之前,一切都正常工作。当eof标志被设置时,我不能移动我的get指针。我试过了:

if(file.eof())
{
   file.clear();
   file.seekg(0 , ios::end)
}

…然后删除字符串末尾的空白。这几乎起了作用。该函数提取不带空格的字符串,但我得到一个无限循环。

我的实际问题是:我如何检查下一个字符是否为EOF,如果我不能-是否有其他方法可以做到这一点?

下面是我的实际功能:

bool readNextString(ifstream &file , char* &pBuffer)
{
    if(file.eof()){
        return false;
    }
    for(; file.good() && isWhitespace(file.peek()) && !file.eof() ; file.seekg(1 , ios::cur))
        ;
    if(file.eof()){
        cout << "The file is empty.n";
        return false;
    }else{
        streamoff startPos = file.tellg();
        cout << "startPos : " << startPos << endl;
        for(;file.good() && file.peek()!='n' && file.peek()!=',' && file.peek()!= EOF; file.seekg(1 , ios::cur))
            ;
        streamoff A = file.tellg();
        cout << "A : " << A << endl;
        file.seekg(-1 , ios::cur);
        for(;file.good() && isWhitespace(file.peek()) ; file.seekg(-1 , ios::cur))
            ;
        file.seekg(2 , ios::cur);
        streamoff endPos = file.tellg();
        cout << "endPos : " << endPos << endl;
        pBuffer = new char[endPos-startPos];
        if(pBuffer)
        {
            file.seekg(startPos , ios::beg);
            file.get(pBuffer , endPos-startPos , ',' || 'n');
            for(;file.good() && file.peek()!='n' && file.peek()!=',' && file.peek()!= EOF; file.seekg(1 , ios::cur))
                ;
            file.seekg(2 , ios::cur);
            streamoff temp = file.tellg();
            cout << "temp : " << temp << endl;
            return true;
        }else{
            cout << "Error! Not enough memory to complete the task.nPlease close some applications and try again.n";
            return false;
        }
    }
}

这就是我称之为

的地方
void printCities()
{
    ifstream city ;
    city.open("cities.txt", fstream::in);
    if(city.is_open())
    {
        char *currCity;
        int counter = 1;
        while(readNextString(city , currCity))
        {
            cout << counter++ << ". " << currCity << endl;
            delete[] currCity;
            currCity = NULL;
        }
        if(city.eof())
            cout << "There are no cities added.n";
        city.close();
    }else
        cout << "Error by opening 'cities.txt'.Make sure that the file exist and try again.n";
}

希望我说得够清楚。如果你发现其他错误或可能的错误,我很高兴听到并从中吸取教训。

如何检查下一个字符是否为EOF?

这样的

if (file.peek() == EOF)
{
    // next char is EOF
    ...
}

首先,不要使用seek来跳过空白。只要拿到字符和完成它。

第二,你似乎误解了…的意思istream::good()istream::eof()。有never只要istream::good()是合适的,并且istream::eof()通常只适用于输入后的失败了。至于你的循环跳过空白,通常的解决方案是:
while ( isspace( file.peek() ) && file.peek() != EOF ) {
    file.get();     //  ignore read character...
}

类似的注释也适用于其他循环,除了您不会想要忽略已读字符。收集字符到下一个',',例如:

std::string field;
while ( file.peek() != ',' && file.peek() != EOF ) {
    field.push_back( file.get() );
}

(和你的file.get( pBuffer, endPos - startPos, ',' || 'n' )当然不会像你期望的那样;表达式',' || 'n'将始终求值为true,在转换时(对于char,是'1)

最后,虽然上面的策略可以工作,但它是更可取的将较大的文本单元输入std::stream,并进行解析那如果文本是行导向的,则使用如下命令:

std::string line;
while ( std::getline( file, line ) ) {
    //  Parse line, using std::istringstream if appropriate,
    //  although this doesn't seem to be the case for your code.
}

这比你现在做的要简单得多

好的。我不是这么做的!getline()用于WIN !: D这是我的代码(这一次可读性更强了):

bool readNextString(ifstream &file , char pBuffer[] )
{
    while(isWhitespace(file.peek()) && !file.eof())
        file.ignore(1);
    if(!file.eof())
    {
        streamoff start = file.tellg();
        stringstream toComma;
        if(file.getline(pBuffer , 200 , ','))
        {
            toComma << pBuffer;
            toComma.getline(pBuffer ,200, 'n');
            int i=strlen(pBuffer)-1;
            for(; isWhitespace(pBuffer[i]) ;i--)
                ;
            pBuffer[i+1] = '';
            file.clear();
            file.seekg(start + strlen(pBuffer) , file.beg);
            return true;
        }else return false;
    }
    return false;
}

我也对我的其他功能做了一些改变:

void printCities()
{
    ifstream city ;
    city.open("cities.txt", fstream::in);
    if(city.is_open())
    {
        if(!isEmpty(city))
        {
            char currCity[200];
            int counter = 1;
            while(readNextString(city , currCity) && counter < 10)
                cout << counter++ << ". " << currCity << endl;
        }else
            cout << "There are no cities added.n";
        city.close();
    }else
        cout << "Error by opening 'cities.txt'.Make sure that the file exist and try again.n";
}

如果文件为空,函数isEmpty(ifstream &file)返回true,否则返回false。

感谢大家的帮助!

最新更新