当检查是eof时,使用getline从文本文件中读取会导致无限循环

时间:2013-02-26 23:24:05

标签: c++ windows file text

我正在尝试从特定行(第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”和“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);
    }
}

它有效。

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

3 个答案:

答案 0 :(得分:2)

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

至于第一个版本错误的原因:是否设置了eof 在最后一次成功阅读之后,或在第一次成功阅读之后, 没有真正指定。当然,还有其他原因 输入可能会失败,而不是文件结束。成熟的习语 是总是使用getline(以及任何其他输入)作为 控制循环或if中的表达式。如果表达式是 考虑true,输入成功。它有时是 在知道输入失败后检查eof()很有用; 如果eof()不成立,则问题出在其他地方: 硬件错误(bad()为真)或错误 格式。

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

答案 1 :(得分:2)

在这里(不要忘记阅读评论):

示例:

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

For-loop方法,简洁明了:

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

答案 2 :(得分:1)

第二个文件具有无与伦比的行数,因为您期望7行,并且它的最后一个块少于该行。这导致你在检查之前超出了eof。你需要将eof条件放在内部for循环中。

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