奇怪的seekg()还有seekp()

      最近在做大作业写一个不让用数据库的图书管理系统,感觉到了c++的暴力

      先来描述一下我们的做法:用户信息,书籍信息,日志文件…… 统一用.txt存储,也就是说代码里充满了对文件的操作。

      我在做修改用户欠款的时候发现seekg()和seekp()和想象中的一点也不一样,好气哦(>人<;)。折腾了好久~

      先说一下seekg()和seekp()函数吧:

      C++ I/O系统管理两个与一个文件相联系的指针。一个是读指针,它说明输入操作在文件中的位置;另一个是写指针,它下次写操作的位置。每次执行输入或输出时,相应的指针自动变化。所以,C++的文件定位分为读位置和写位置的定位,对应的成员函数是 seekg()和 seekp(),seekg()是设置读位置,seekp是设置写位置。

       函数原型:
          ostream& seekp( streampos pos );
          ostream& seekp( streamoff off, ios::seek_dir dir );
          istream& seekg( streampos pos );
          istream& seekg( streamoff off, ios::seek_dir dir );
  函数参数
          pos:新的文件流指针位置值
          off:需要偏移的值
          dir:搜索的起始位置
          dir参数用于对文件流指针的定位操作上,代表搜索的起始位置
          在ios中定义的枚举类型:
              enum seek_dir {beg, cur, end};
              每个枚举常量的含义:
                  ios::beg:文件流的起始位置
                  ios::cur:文件流的当前位置
                  ios::end:文件流的结束位置


      就是酱紫!看起来明明是超级可爱的函数,可以向光标一样,”想读哪里移哪里,想写哪里朝哪走“!结果在我感觉自己萌萌嗒的时候,果然被自己蠢了一脸血~

      以下是错误的示范(小一点,假装你们可以忽略)

       我的用户信息是酱紫的:

      user.txt

   (用户类型老师0学生1 姓名 证件号 学院 信用度 权限 欠款)
     0 刘德华 00000001 人文 5 5 0
     0 周华健 00000002 人文 5 5 10.20

     0 蔡依林 00000003 日语 5 5 2.80 
     1 李宇春 00000004 信通 5 4 0 

    

     在代码部分,我就灰常开心的打开了文件!

       fstream fptr;

fptr.open("user.txt", ios::in|ios::out);

然后getline();一行一行的读文件,寻找假装欠了我钱的人,(测试数据中是00000002欠了我的钱!)前面的都很顺利,找到用户,读取之前的欠款,算当前的总欠款,到这里一丢丢问题都没有!但是悲伤来的太突然,当我用起了fptr.seekp(-k,ios::cur);(-k是欠款长度),运行完毕后,我满心期待的打开了user.txt,结果发现“蔡依林”被覆盖了!

然后我就做了如下操作:seekg(0,cur);

getline(fptr,s);

果然被结果吓到了:贴给你们看(=====74======是字数(电脑把汉字算两个了))

奇怪的seekg()还有seekp()_第1张图片

      就是说当前的 指针活脱脱的指到了很奇怪的地方。

     为了找原因改了一下程序方便查看错误的样子

样子

     在我测试多组数据后我构造了一个递增数列来平衡这乱跑的光标,但是数据数量再加大还是有错误......最后以失败告终。

     之后就去测试纯数字数据纯英文数据,都不符合我美好的想象。看来是文本文档的读入多多少少都不太正常,于是我选择了以二进制的形式读入文档:

fstream fptr;

fptr.open("user.txt", ios::in|ios::out|ios::binary);

然后就木有问题啦!有图有真相

真相

getline()后光标就跑到了下一行的行首~这样子只需计算字节数来回挪动就能合情合理的修改任意位置的光标啦(移动光标的时候用int i=i*sizeof(char),i表示偏移量)!

但是为什么是这样的呢?

  在windows系统下读取文本文档遇见换行会变成 "\r\n"

但是若以二进制的方式读取就没有"\r"了

    

    


         

学习过程中参照的blog:

文件的操作:http://blog.csdn.net/mafuli007/article/details/7314917

c++ 以二进制和以文本方式读写文件的区别http://www.cnblogs.com/litaozijin/p/6582048.html

你可能感兴趣的:(c++从入门到放弃)