如何在文件结束后阅读文件的开头?

时间:2016-09-22 03:39:13

标签: c++ file windows-10 codeblocks

让我的文件包含:(文件名:PROFILE.txt)

1 2 3 4 5`

我使用以下代码阅读并获取数据

#include <iostream>
#include <fstream>
using namespace std;
fstream profile;
int n;
int main()
    {
        profile.open("PROFILE.txt",ios::app|ios::in|ios::out); // file name is PROFILE.txt
        long start = profile.tellg(); //marks the point of beginning of the file
        a:
        profile>>n;
        long p = profile.tellg(); //marks the current point of the file cursor
        cout<<n<<" "<<p<<endl;
        if(n==5)profile.seekg(start); // or if(p==-1)profile.seekg(start);
        goto a;
        return 0;
    }

输出为:

1 1
2 3
3 5
4 7
5 -1
5 -1 
5 -1
5 -1
..
...
.... //so on

但是,预期输出(或我想要的输出):

1 1
2 3
3 5
4 7
5 9
1 1
2 3
3 5
4 7
5 9
1 1
2 3
3 5
4 7
5 9
.
..
... //so on

问题: 问题是它到达文件的末尾!它无法转到文件的开头!并且不服从seekg();!但是假设如果没有达到它的目的那么它应该可以正常工作!

我的错误是什么以及如何解决它!什么应该是代码?

请注意:我是c ++初学者!所以请尝试通过简单的C ++程序代码回答我,请尝试一步一步地回答我!

我希望你理解我的节目和我的问题!

PICTURE of my CODE,OUTPUT,FILE

After Serge Ballesta code fix

请注意以下代码和输出来自CODE:在Windows 10(64位)PC中运行的BLOCKS(最新版本) (其他信息: i7处理器,内存:16GB,GPU:4GB)

TO SEE MY OTHER Questions

2 个答案:

答案 0 :(得分:0)

使用if (n == 5) ...进行测试时无法重现。我甚至无法想象你的系统如何给你这个结果!

以下是我系统上发生的事情:

  • 读取数字1到4并在数字
  • 之后立即定位在文件中
  • 在文件结尾
  • 之前读取数字5和位置9 的位置
  • 由于未检测到任何错误,执行seekg并重新提交文件

所以我得到了(比如@ user3286661)1 1 2 3 3 5 4 7 5 9 1 1 2 3 ...(新的行为brievety省略)。根据标准,这是正常输出。

但如果我使用if (p == -1) ...,我会得到(差不多)你的输出,因为现在发生以下情况

  • 读取数字1至5,并在文件结束前的第9位
  • 下次读取命中文件的结尾。从那时起,每次访问profile都会产生错误,因为我们现在已经过了文件结尾
  • p = profile.tellg()返回-1
  • 由于文件错误,
  • profile.seekg(0)未执行
  • profile >> n不会更改保留在5
  • n的值

所以我得到了(按照标准规定):1 1 2 3 3 5 4 7 5 9 5 -1 5 -1 ...(新行仍然省略)

如何修复:只需清除错误条件:

if (p == -1) {
    profile.clear();
    profile.seekg(0);
}

但是这种编程需要注意以下几点:

  • 你使用goto,其中while循环会好得多。 goto永远不应该用于循环,只能用于非常特殊的用例,因为它不会使结构明显
  • 您从未在任何操作后测试流的状态。这是你问题的真正原因。如果您已经完成,那么profile流在eof之后仍然处于seekg模式并且必须清除坏情况

答案 1 :(得分:0)

固定代码:

TimeZoneInfo timeZoneInfo;
DateTime dateTime;
timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("E. Australia Standard Time");
dateTime = TimeZoneInfo.ConvertTime(DateTime.Now, timeZoneInfo);
DateTime AusDateTime= dateTime.ToString("yyyy-MM-dd HH-mm-ss");


_activityService.InsertActivity(new ActivityDto { UserName = HttpContext.Current.User.Identity.Name, ActivityType = ActivityConstants.ACT_TYPE_USR_MGT, ActivityDescription = ActivityConstants.USR_MGT_DESCR_FORGOT_PW, ActivityDate = DateTime.Now });

节目输出:

PROGRAM OUTPUT

特别感谢Serge Ballesta(感谢他的帮助以及他的代码段)

如果有比这更好更简单的方法,请告诉我。