1

我正在尝试从特定行中的文本文件中获取一些数据(第 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);
    }
}

它奏效了。

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

4

3 回答 3

2

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

至于为什么第一个版本是错误的:是eof在最后一次成功读取之后设置,还是在第一次不成功之后设置,并没有真正指定。当然,除了文件结尾之外,还有其他原因导致输入失败。神圣的习惯用法是始终使用getline(和任何其他输入)作为循环或 if 中的控制表达式。如果表达式被考虑true,则输入成功。在您知道输入失败后进行检查有时很有用eof()如果eof()不是真的,那么问题出在其他地方:硬件错误(bad()为真)或格式错误。

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

于 2013-02-26T23:51:15.620 回答
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( );
    }
};
于 2013-02-27T03:24:48.003 回答
1

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

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

于 2013-02-26T23:31:36.047 回答