I/O流类库(三)

文件的读写


  • >>
  • <<
  • get
  • put
  • read
  • write
  • 文本模式打开与二进制模式打开区别

>> 、<<

#include <iostream>
#include <fstream>
#include<cassert>
#include<string>

using namespace std;

int main(void)
{
    ofstream fout("test.txt");
    fout << "abc" << "  " << 200;
    fout.close();  

    ifstream fin("test.txt");
    string s;
    int n;
    fin >> s >> n;
    cout << s << "  " << n << endl;
}

这里写图片描述

get、put

#include <iostream>
#include <fstream>
#include<cassert>
#include<string>

using namespace std;

int main(void)
{
    ofstream fout("test2.txt");
    char ch;
    for (int i = 0; i < 26; i++)
    {
        ch = 'A' + i;
        fout.put(ch);
    }
    fout.close();

    ifstream fin("test2.txt");
    while (fin.get(ch))
    {
        cout << ch;
    }
    cout << endl;
}

这里写图片描述

文件模式打开与二进制模式打开的区别


  • 如果以文本的方式打开文件,写入字符的时候,遇到\n会做转换,写入\r不做转换
    • windows平台\n转为 \r\n
    • linux平台保留不变
    • mac系统\n转为\r
  • 如果以二进制的方式打开文件写入字符时,遇到\n不会做转换
  • 以文本方式打开文件,也可以写入二进制数据;以二进制方式打开文件也可以写入文本
    • 写入的数据是二进制还是文本,与打开方式无关,与写入使用的函数有关
    • 要写二进制数据,应该用write,相应的读要用read

二进制文件的读写


  • 二进制文件不同于文本文件,它可用于任何类型的文件(包括文本文件)
  • 对二进制文件的读写可采取从istream类继承下来的成员函数read()和从ostream类继承下来的成员函数write()
  • 文件打开操作时使用枚举常量ios::binary,例如
    ofstream fout(“binary.dat”, ios::out | ios::binary);

write()成员函数


  • 函数功能:以字节单位向文件流中写入整块数据,最有价值的应用可以处理结构体变量和类对象
  • 函数原型:ostream& write(const char* pch, int nCount);
  • 函数的参数:
    • pch 写入的数据的指针
    • nCount 写入数据的字节大小

read()成员函数


  • 函数功能:从文件流中读出整块数据
  • 函数原型:istream& read(const char* pch, int nCount);
  • 函数的参数:
    • pch 用来接收数据的指针
    • nCount 读取字节数的大小

#include<iostream>
#include <fstream>
#include<string>

using namespace std;
struct Test
{
    int a;
    string b;
    string c;
};
int main(void)
{
    Test t1;
    t1.a = 100;
    t1.b = "xxxccccccccccccccccccccaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaawwwwwwwwwwwwwwwwwwwwww";
    t1.c = "yyyeeeeeeeeeeeeeeeeeeeeebbbbbbbbbbbbbbbbbbbbbbbbbbbbbyyyyyyyyyyyyyyyyyyyyyyy";
    cout << "sizeof(string) = "<<sizeof(string) << endl;
    cout << "sizeof(Test) = "<<sizeof(Test) << endl;
    cout << "sizeof(t1) = " <<sizeof(t1) << endl;
    ofstream fout("test4.txt", ios::out | ios::binary);
    fout.write(reinterpret_cast<char*>(&t1), sizeof(t1));
    fout.close();
    Test t2;
    ifstream fin("test4.txt", ios::in | ios::binary);
    fin.read(reinterpret_cast<char*>(&t2), sizeof(Test));
    cout << t2.a << endl; 
    cout << t2.b << endl;
    cout<< t2.c << endl;
    fin.close();

    return 0;
}

这里写图片描述这里写图片描述

string和Test结构提的大小总是不变的,而字符串内容的大小在变,在写入和读取的时候就会出错!最好是要分开读取和写入!

#include<iostream>
#include <fstream>
#include<string>

using namespace std;
struct Test
{
    int a;
    string b;
    string c;
};
int main(void)
{
    Test t1;
    t1.a = 100;
    t1.b = "xxxccccccccccccccccccccaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaawwwwwwwwwwwwwwwwwwwwww";
    t1.c = "yyyeeeeeeeeeeeeeeeeeeeeebbbbbbbbbbbbbbbbbbbbbbbbbbbbbyyyyyyyyyyyyyyyyyyyyyyy";
    int len = 0;
    ofstream fout("test4.txt", ios::out | ios::binary);
    fout.write(reinterpret_cast<char*>(&t1.a), sizeof(int));    
    len = t1.b.length();
    fout.write(reinterpret_cast<char*>(&len), sizeof(int));
    fout.write(t1.b.data(), t1.b.length());
    len = t1.c.length();
    fout.write(reinterpret_cast<char*>(&len), sizeof(int));
    fout.write(t1.c.data(), t1.c.length());
    fout.close();
    Test t2;
    ifstream fin("test4.txt", ios::in | ios::binary);
    fin.read(reinterpret_cast<char*>(&t2.a), sizeof(int));
    fin.read(reinterpret_cast<char*>(&len), sizeof(int));
    t2.b.resize(len);
    fin.read(reinterpret_cast<char*>(&t2.b[0]), len);
    fin.read(reinterpret_cast<char*>(&len), sizeof(int));
    t2.c.resize(len);
    fin.read(reinterpret_cast<char*>(&t2.c[0]), len);
    cout << t2.a << endl; 
    cout << t2.b << endl;
    cout<< t2.c << endl;
    fin.close();

    return 0;
}

这里写图片描述

当前文件流活动指针


  • 文件流指针用以跟踪发生I/O操作的位置
  • 每当从六中读取或写入一个字符,当前活动指针就会向前移动
  • 当打开方式中不含有ios::ate或ios::app选项时,则文件指针被自动移到文件的开始位置,即字节地址为0的位置。

文件的随机读写

seekp和seekg


  • 函数功能
    • seekp: 设置输出文件流的文件流指针位置
    • seekg: 设置输入文件流的文件流指针位置
  • 函数原型
    • ostream& seekp(streampos pos);
    • ostream& seekp(streamoff off, ios::seek_dir dir);
    • ostream& seekg(streampos pos);
    • ostream& seekg(streamoff off, ios::seek_dir dir);
  • 函数参数
    • pos:新的文件流指针位置值
    • off:需要偏移的值
    • dir:搜索的起始位置

tellp和tellg


  • 函数功能
    • tellp: 获得输出的文件流指针的当前位置,以字节为单位
    • tellg: 获得输入的文件流指针的当前位置,以字节为单位
  • 函数原型
    • streampos tellp();
    • streampos tellg();
  • 函数的返回值: 实际上是一个long类型

这里写图片描述

#include<iostream>
#include <fstream>
#include<string>
#include <cassert>

using namespace std;

int main(void)
{
    ifstream fin("test5.txt");
    assert(fin);
    char ch;

    fin.seekg(2);   
    fin.get(ch);
    cout << ch << endl;

    fin.seekg(-1, ios::end);
    fin.get(ch);
    cout << ch << endl;

    fin.seekg(0, ios::end);
    streampos pos = fin.tellg();
    cout << pos << endl;        //此方法可判断文件大小

    return 0;
}

这里写图片描述

seek_dir


  • dir参数用于文件流指针的定位操作上,代表搜索的起始位置
  • 在ios中定义的枚举类型
    enum seek_dir {beg, cur, end};
  • 每个枚举变量的含义
    • ios::beg:文件流的起始位置
    • ios::cur :文件流的当前位置
    • ios::end:文件流的结束位置

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值