0

我有一个文件,我只想将最后一行输出到控制台。

这是我对如何做到这一点的想法。用于file.seekg(0, ios::end)将自己置于文件末尾。

然后,我可以创建一个递减变量int decrement = -1;并使用一个 while 循环

 while (joke.peek() != '\n')
 {
     decrement--;

 }

并获得我最后一行的起始位置(从末尾向后)。

知道这一点,joke.seekg(decrement, ios::end);应该将我设置到最后一行的开头,并假设我之前声明过string input; 我会认为

 getline(joke, input);
 cout << input << endl;

会将其输出到控制台。

完整代码

 void displayLastLine(ifstream &joke)
 {
    string input;
    int decrement = -1;


    joke.clear();
    joke.seekg(0, ios::end);


    while (joke.peek() != '\n')
    {
        decrement--;

    }
    joke.clear();

    joke.seekg(decrement, ios::end);

    getline(joke, input);
    cout << input << endl;

}

问题是,当我为文件调用此方法时,什么也没有发生。当我逐步通过它时,减量只是继续减去一个,远远超出了 a 的范围'\n'。举一个文本文件的例子,它看起来像这样:

垃圾

垃圾

跳过这一行

这是我们正在寻找的线路!

4

3 回答 3

1

peek不移动文件指针,它读取字符而不提取它。因此,您不断地查看相同的值(字符)并最终陷入无限循环。

您需要做的是:

while (joke.peek() != '\n')
{
    joke.seek(-1, ios::cur);
}

这会将输入位置放在\n,使用 的第二个重载seekg

请注意,这不是一个完美的解决方案。您需要检查错误和边界条件,但它解释了您观察到的行为并为您提供了开始修复代码的一些东西。

于 2016-05-18T01:11:58.410 回答
1
joke.seekg(0, ios::end);

这会将文件定位在末尾。

while (joke.peek() != '\n')

好吧,这是问题#1。当您在文件末尾时,peek()始终返回EOF.

    decrement--;

你写:

当我逐步通过它时,减量只是继续减一,

好吧,您期望会发生什么,因为这是循环所做的唯一事情?你的循环唯一要做的for就是从decrement. 所以这就是发生的事情。

这是一个常见的问题:计算机只做你告诉它做的事情,而不是你想让它做的事情。

虽然这不是最佳的,但您缺少的步骤是在您之前peek(),您需要seek()后退一个字符。然后,peek()显示当前光标位置的字符。然后,再seek()返回一个字符,并peek()再次检查,以此类推。

但这对你来说仍然不够。大多数文本文件都以换行符结尾。也就是说,换行符是文件中的最后一个字符。因此,即使您添加回缺失的seek(),在几乎所有情况下,您的代码最终都会找到文件中的最后一个字符,即最后一个换行符。

我给你的建议是暂时停止编写代码,而是想出一个逻辑过程来做你想做的事情,并用简单的语言描述这个过程。然后,与你的橡皮鸭讨论你提议的行动方案。只有在您的橡皮鸭同意您的建议可行之后,然后将您的简单语言描述翻译成代码。

于 2016-05-18T01:15:25.977 回答
0

您的循环实际上只是递减“递减”,而不是使用它来进行下一次搜索。

while (joke.peek() != '\n')

{
    joke.seekg(decrement, std::ios::end);
    decrement--;
}
于 2016-05-18T01:54:13.590 回答