当check为eof时,使用getline读取文本文件会导致无限循环

Using getline to read from text file leads to infinite loop when check is eof

本文关键字:文件 取文本 无限循环 读取 getline check eof 使用      更新时间:2023-10-16

我正试图从特定行的文本文件中获取一些数据(第1行、第7行、第13行等-所需数据放在下一个第6行(

到目前为止,我的代码是:

txtfile = "titles.txt";
ifstream txt(txtfile);
const int buffer_size = 80;
char title_buffer[buffer_size];
const int titleLineDiff = 6;
if (txt.is_open())
{
    while(!txt.eof())
    {
        static int counter = 1;
        txt.getline(title_buffer, buffer_size);
        cout << "Title: "" << counter << "." << title_buffer << """ << endl;
        counter++;
        //seek to the next title...difference is 6 lines
        for(int i = 0; i < titleLineDiff; i++)
            txt.getline(title_buffer, 40);
    }
}

现在,它可以很好地与我创建的这个文件配合使用:

testONE
two
three
four 
five
six
testTWO
bla

它打印"testONE"answers"testTWO",但当我试图打开包含数据的文件时,我会得到一个无限循环,输出是

标题:"counter_increasing_number。">

文本文档是从互联网上复制的,这可能是阅读问题的原因。

我该怎么办?


我已将代码更改为:

while(getline(txt,title_buffer))
{
    static int counter = 1;
    //getline(title_buffer, buffer_size);
    cout << "Title: "" << counter << "." << title_buffer << """ << endl;
    counter++;
    //seek to the next title...difference is 6 lines
    for(int i = 0; i < titleLineDiff; i++)
    {
        getline(txt, title_buffer);
    }
}

它奏效了。

有人能解释一下第一个不起作用的原因吗?

对于初学者,您使用的是getline的结果检查是否成功。(在第二个版本中,这是仅适用于内部循环。(

至于为什么第一个版本是错误的:是否设置了eof在最后一次成功读取之后或在第一次不成功读取之后,并没有真正指定。当然,还有其他原因除了文件结尾之外,输入可能会失败。成语是总是使用getline(和任何其他输入(作为控制循环或if中的表达式。如果表达式为考虑到true,输入已经成功。有时在您知道输入失败后检查eof()非常有用;如果eof()不是真的,那么问题出在其他地方:硬件错误(bad()为真(或总体安排

至于为什么你的测试数据和实际数据表现不同,很难说两者都看不到。一些可能的原因:不同的行尾约定,也许是一组数据以不完整的行结尾(如果数据使用Windows编辑器生成(,或比缓冲区(在第一种情况下(。

给你(别忘了阅读评论(:

示例:

void Example( void )
{
    // DECLARATION
    // *Declare iFile as std::ifstream and attempt to open file: Example.txt
    std::ifstream iFile( "Example.txt" );
    // *If iFile is open, do this:
    if( iFile.is_open( ) )
    {
        // DECLARATION
        // *You could declare strLine as an array of char if you want
        std::string strLine = "";
        unsigned int nLineCount = 0;
        // DO WHATEVER
        // *Read iFile line by line using std::getline
        while( std::getline( iFile, strLine ) )
        {
            // *For the line after every 6th line, we shall print
            // as a title
            // *( nLineCount % 6 ) gives us the remainder of
            // nLineCount / 6 and if the remainder is 0, then
            // do this:
            if( !( nLineCount % 6 ) )
            {
                std::cout << "Title = " << strLine << std::endl;
            }
            // *For every other line, we shall print it normally
            else
            {
                std::cout << strLine << std::endl;
            }
            // *Increase nLineCount by 1;
            nLineCount ++;
        }
        // CLEAN-UP
        // *Done using inFile - so close it
        inFile.close( );
    }
};

已测试:

Title = 1
2
3
4
5
6
Title = 7
8
9
10
11
12
Title = 13
...
Debugging > Paused! Enter any key to continue...

更多无评论:

void Example( void ) {
    std::ifstream iFile( "Example.txt" );
    if( iFile.is_open( ) ) {
        std::string strLine = "";
        unsigned int nLineCount = 0;
        while( std::getline( iFile, strLine ) ) {
            if( !( nLineCount % 6 ) )
                std::cout << "Title = " << strLine << std::endl;
            else
                std::cout << strLine << std::endl;
            nLineCount ++;
        }
        iFile.close( );
    }
};

对于循环法,短而干净:

void Example( void )
{
    std::ifstream iFile( "Example.txt" );
    if( iFile.is_open( ) )
    {
        std::string strLine = "";
        for( unsigned int nLineCount = 0; std::getline( iFile, strLine ); nLineCount ++ ) {
            if( !( nLineCount % 6 ) )
                std::cout << "Title = " << strLine << std::endl;
            else
                std::cout << strLine << std::endl;
        }
        iFile.close( );
    }
};

第二个文件的行数不相等,因为您预计会有7行,而最后一个块的行数小于7行。这导致您在检查之前超出了eof。您需要将eof条件放入内部for循环中。

编辑:请确保每行不超过80个字符。