第14&15周CPP整理(二进制文本读写,随机文件)

 

二进制读写是周二老师所讲的内容,而什么叫二进制读写呢,就是一个文件打开是乱码,虽然看不懂,但是可以通过另外的方式打开,上课老师所打开的方式是UltraEdit,

然而二进制文本的坏处便是看见的是一堆乱码,并且不能直接看到内容,但是二进制非常省空间,所以各有好处坏处,两个文件读取的方式一模一样,接下来关于文本的例子如下:


可以看见这段代码copyfile是一个类,做的是从srcFile读取文件,然后再放到dstfile中,如果既不是输入也不是输出的话,就打印打开失败,循环里面读一个写一个读一个写一个。(但是要注意的一点便是用完读写流后就要关闭,这样以免出现一些奇怪的问题)

可以看见这里老师在操作的时候打开失败了,并且说一定需要那个ULTRA EDIT(下面就简称UE),打开失败的原因是因为找不到那一个作为复制原本的文件。那我们就可以知道在读写的时候需要复制文本存在的情况下才能成功读取,这是一个非常重要的经验。然后我们可以看到,老师复制读取的是图片,这说明二进制读写可以读写照片,这与我们之前所认识的文本复制读取大大不同,在我之前的认识中,读写图片我一直以为需要算法,但是现在看来算法并不是必须的。

言归正传,我们回到UE,可以理解到每一行都会表示一个或两个字符,但是上课老师在操作的过程中失败了,这里的话就是如果复制粘贴的时间不对的话,那就意味着错了,其实这是一个很好的判别自己的文件有没有错的办法,如果文件的时间可以和当前的内容所匹配,就意味着是对的。当前能想到最好的解决办法就是把过去的创建过的文件删掉。看看是否编译时会在产生一个文件,如果没有,也就是在创建文件时除了问题。

然后我们再来看一段代码,sizeof student 因该是18,但是要考虑整数边界,Score占了8个字节,那么取得内存就一定要从八个字节开始,所以前面的name看起来取了10个,实际上取了16个,因为要是8的倍数,再加上8的score,总共需要24个字节。而这段代码的意思是S的资料写进文件,然后写进T里面去。然后项目里面可以看见Data.date,不存在,但是运行完后就会出来,而右边的前面五行左右就是对于打开data.date的一个操作,创建或者打开,否则输出“文件打开失败”

这张图就是把代码前面运行的结果,可以看到CC代表的是空的意思,而54 40代表的意思则是EOF.EOF用来判断程序是否结束。

程序代码如下:

 
#include<iostream>
#include<fstream>
#include<string>
using namespace std;

int main()
{
 ifstream data1("w20in-1.dat", ios::binary);
 ofstream data2("w20-out1.dat", ios::binary);
 char ch;
 int cnt = 0;
 while (data1.get(ch)&&cnt<=20)
 {
  cnt++;
  data2.put(ch);
 }
  
 data1.close();
 data2.close();
 return 0;
 
}





这段代码的意思就是我上课做的从文件中读取20个字符到文件,但是因该不是最好的


然后接下去的例子是打印双数的字符(从偶数打一个跳一个)

代码如下:

#include<iostream>
#include<fstream>
#include<string>
using namespace std;

int main()
{
 ifstream data1("w20in-2.dat", ios::binary);
 ofstream data2("w20-out2.dat", ios::binary);
 char ch;
 int cnt = 1;
 while (data1.get(ch))
 {
  if (cnt%2==0)
  data2.put(ch);
  cnt++;
 }
  
 data1.close();
 data2.close();
 return 0;
 
}


图中的烫烫烫毫无问题,给的文件里面原本就存在的,而这个功能便是打印双数了




——————————————————————————————————--


这节上课所讲的是随机文件读写,就是读文件不一定要从头开始,这里有三个概念:

ios::beg  就是ios流开始的地方,就是从文件开始处写

ios::cur顾名思义后面是CURRENCY的意思,就是从文件当前位置开始(seek 跟Tell)

ios::end是从文件的末尾处读写

而每一个文件打开都会有一个光标。

而移动读写指针也就是光标有两种方法,第一种是直接跳到他的位置,还有一种就是利用偏移量去改变。

这个知识点涉及到cursor,意思也就是光标的意思啦

而跳转光标的用法就是用fin.seek这种用法,如果说是fin,也就是读写流的话,需要加一个G,但是如果是fout也就是输出流的话

那就需要加个P

所以具体的用法就是fin.tellg();这种,意思也就是取fin读指针的偏移量

具体的例子如下:



而其中的while(fin.peek()!=EOF)

的意思便是如果还可以读的到字符,就是没有读到末尾的情况


这个代码的意思就是把代码中给的数据存入文件中,然后再从文件中读取数据打印在荧幕上,代码中的前面三行如果不加的话第一次运行程序会报错,接下去运行也是不同,再怎么试也是不行的,因为他根本就没有创建一个文件。


而这一段代码改变了三行,主要改的就是SEELG不是从0开始了,也就是说我们可以发现SEEKG的第一个参数的作用是开始的位置,中的意思就是跳到开始+第一个参数长度的位置。而打开一个文件的话,在创建文件的同时,会刷新里面的内容,也就是把文件变成空。




ate是一个新的东西,意思大致是把光标移到文件的最后面去,这需要再确认一下。查了一下,tellp是一个询问指针位置的函数,也就是changepos可以通过这个函数获取指针的位置。注意,是覆盖,而不会往后移动。所以随机文件的意思并不是随机读取文件,而是我想在那改动就在那改动,这个思想跟我在大作业中解决时间复杂性的处理是差不多的。

最后再附上一张知识表:


read一次读一行,eof告诉是否结束,gcount统计字符数,其实就相当于字数统计。peek,看一眼光标然后已过去,tellp一个是get,一个是Put.

——————————————————————————————————

这个知识点还没有讲完,所有的知识点也是很浅的,这个博客这几天我会继续更新一下




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值