7.4 文件操作与文件流

7.4 文件操作与文件流

7.4.1 文件的概念

文件是指存储在外部介质上数据的集合,程序文件,数据文件
数据文件又分为ASCII文件二进制文件

对于字符信息,在内存中是以ASCII码形式存放的,因此,无论是用ASCII文件输出还是二进制文件输出,其数据形式都是一样的,但对于数值二者是不同的。

高级I/O功能是把若干字节组合成一个有意义的单位,然后以ASCII码的形式输入输出。

低级I/O功能是以字节为单位输入输出的,输入输出时不进行类型转换。(以二进制形式)

7.4.2 文件流类与文件流对象

输出输出都是对内存而言的。

三个文件类:
ifstream/ofstream/fstream

建立一个文件流对象:
ofstream outfile;

7.4.3 文件的打开与关闭

1.打开磁盘文件

打开文件是指在文件读写前所做的必要准备工作,包括:
A. 为文件流对象和文件之间建立关联;
B. 指定文件的工作方式,输入输出,ASCII或者二进制文件;

两种方法实现:
1. 调用文件流成员函数open

ofstream outfile;
outfile.open("f1.dat", ios::out);
  1. 在定义文件流对象时就指定参数。
ostream outfile("f1.dat", ios::out);      //较为常用


输入输出方式:

ios::in
ios::out

ios::app
ios::ate
ios::trunc

ios::binary

ios::in | ios::out
ios::out | ios::binary

如果打开操作失败,open函数返回值为假(0),如果是调用构造函数的方式打开文件的,则流对象的值为0,可以一次判断文件是否打开成功。

  1. 关闭磁盘文件(断开连接)
outfile.close();

7.4.4 对ASCII文件的操作

(一) 用流插入运算符<<和流提取运算符>>输入输出标准类型的数据。

(二) 文件流的put,get,getline等成员函数;

// 有一个整型数组,含10个元素,从键盘输入10个整数给数组,将此数组存入到文件中
#include <iostream>
#include <fstream>
using namespace std;

int main()
{
    int a[10];

    ofstream outfile("f1.dat", ios::out);
    if(outfile == 0)
    {
       cerr<< "open error!" << endl;
       exit(1);
    }
    cout<< "Enter 10 integer numbers: " << endl;

    for(int i = 0; i < 10; ++i)
    {  
       cin >> a[i];
       outfile << a[i] << ' ';
    }
    outfile.close();

    return 0;
}

参数ios::out可以不写,ofstream默认为ios::out

// 再从f1.dat中读入10个整数放在数组中,并找出最大的的数及其序列号。
#include <iostream>
#include <fstream>
using namespace std;

int main()
{
    int a[10], max, order;
    ifstream infile("f1.dat", ios::in);

    if(infile == 0)
    {
       cerr << "open error!" << endl;
       exit(1);
    }

    for(int i = 0; i < 10; ++i)
    {
       infile >> a[i];
       cout << a[i] << ' ';
    }
    cout<< endl;

    max= a[0], order = 0;

    for(int i = 0; i < 10; ++i)
    {
       if(a[i] > max)
       {
           max = a[i];
           order = i;
       }
    }

    cout<< "max = " << max << endl << "order =" << order << endl;

    return 0;
}
//从键盘读入一行字符,把字符存在f2.dat中,在把它从磁盘文件读入程序,将其中的小写字母改为大写,再存入f3.dat中
#include <iostream>
#include <fstream>
using namespace std;

void get_from_file();
void save_to_file();

int main()
{
    save_to_file();      //  从键盘读入一行字母存入f2.dat中
    get_from_file();  //  从f2.中读入字符改为大写,再存入f3.dat中

    return0;
}

void save_to_file()
{
    ofstreamoutfile("f2.dat");

    if(!outfile)
    {
       cerr<< "open f2.dat error!" << endl;
       exit(1);
    }

    charc[80];
    cin.getline(c,80);
    for(int i = 0; c[i] != 0; ++i)
       if(c[i]>= 'A' && c[i] <= 'Z' || c[i] > 'a' && c[i] < 'z')
       {
           outfile.put(c[i]);
           cout<< c[i];
       }
    cout<< endl;
}

void get_from_file()
{
    charch;

    ifstream infile("f2.dat", ios::in);
    if(!infile)
    {
       cerr<< "open f2.dat error!" << endl;
       exit(1);
    }

    ofstream outfile("f3.dat");
    if(!outfile)
    {
       cerr<< "open f3.dat error!" << endl;
       exit(1);
    }

    while(infile.get(ch))
    {
       if(ch>= 'a' && ch <= 'z')
           ch= ch - 32;
       outfile.put(ch);
       cout<< ch;
    }
    cout<< endl;
    infile.close();
    outfile.close();
}

7.4.5 对二进制文件的操作

二进制文件除了可以作为输出文件或输入文件,还可以是既能输出也能输入的文件,ASCII文件无法这样。

1. 用成员函数readwrite读写二进制文件

istream &  read(char *buffer, intlen);
ostream & write(const char *buffer, intlen);
#include <iostream>
#include <fstream>
using namespace std;

struct student
{
    char name[20];
    int num;
    int age;
    char sex;
};

int main()
{
    student stud[3] = 
    {
        "Li", 1001, 18, 'f',
        "Fun", 1002, 19, 'm',
        "Wang", 1003, 17, 'f'
    };

    ofstream outfile("stud.dat", ios::binary);
    if(!outfile)
    {
        cerr << "open error!" << endl;
        abort();    // =exit();
    }

    for (int i = 0; i < 3; ++i)
        outfile.write((char *)&stud[i], sizeof(stud[i]));
    outfile.close();

    return 0;
}
#include <iostream>
#include <fstream>
#include <string>
using namespace std;

struct student
{
    string name;
    int num;
    int age;
    char sex;
};

int main()
{
    student stud[3];

    ifstream infile("stud.dat", ios::binary);
    if(!infile)
    {
        cerr << "open stud.dat error!" << endl;
        abort();
    }
    for (int i = 0; i < 3; ++i)
        infile.read((char *)&stud[i], sizeof(stud[i]));

    infile.close();

    for (i = 0; i < 3; ++i)
    {
        cout << "NO." << i+1 << endl;
        cout << "Name: " << stud[i].name << endl;
        cout << "Age: " << stud[i].age << endl;
        cout << "Sex: " << stud[i].sex << endl << endl;
    }

    return 0;
}

2. 与文件指针有关的流成员函数

文件指针,指明当前读写位置。

对于二进制文件,允许对指针进行控制,使它按照移动到所需位置进行读写。

g-get,p-put
gcount() 返回输入文件指针的当前位置

tellg()
seekg(文件中的位置)
seekg(位移量,参照位置)

tellp()
seekp()
seekp()

如果是即可输入,也可输出的文件,则任意用seekg或seekp。

参照位置:

ios::beg()
ios::cur()
ios::end()

3. 随机访问二进制数据文件

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

struct student
{
    int num;
    char name[20];
    float score;
};

int main()
{
    student stud[5] = 
    {
        1001, "Li", 85,
        1002, "Fun", 97.5,
        1004, "Wang", 54,
        1006, "Tan", 76.5,
        1010, "Ling", 96
    };
    fstream iofile("stud.dat", ios::in | ios::out | ios::binary);
    if(!iofile)
    {
        cerr << "open error !" << endl;
        abort();
    }

    for(int i = 0; i < 5; i++)
        iofile.write((char *)&stud[i], sizeof(stud[i]));

    student studl[5];
    for(i = 0; i < 5; i += 2)
    {
        iofile.seekg(i*sizeof(stud[i], ios::beg));
        iofile.read((char *)&studl[i/2], sizeof(studl[0]));
        cout << studl[i/2].num << ' ' << studl[i/2].name << ' ' << studl[i/2].score << endl;
    }
    cout << endl;

    stud[2].num = 1012;
    strcpy(stud[2].name, "Wu");
    stud[2].score = 60;
    iofile.seekp(2*sizeof(stud[0], ios::beg));
    iofile.write((char *)&stud[2], sizeof(stud[2]));
    iofile.seekg(0, ios::beg);

    for(i = 0; i < 5; i++)
    {
        iofile.read((char *)&stud[i], sizeof(stud[i]));
        cout << stud[i].num << " " << stud[i].name << " " << stud[i].score << endl;
    }

    iofile.close();

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值