C++学习心得(6)文件操作与文件流

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);

2.  在定义文件流对象时就指定参数。

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,可以一次判断文件是否打开成功。

3.  关闭磁盘文件(断开连接)

outfile.close();

 

7.4.4  对ASCII文件的操作

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

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


// 有一个整型数组,含10个元素,从键盘输入10个整数给数组,将此数组存入到文件中
#include <iostream>
#include <fstream>
using namespace std;
 
int main()
{
    inta[10];
 
    ofstreamoutfile("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中
//从键盘读入一行字符,把字符存在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. 用成员函数read和write读写二进制文件

istream &  read(char *buffer, int len);

ostream & write(const char *buffer, int len);

 

#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、付费专栏及课程。

余额充值