09笔记 IO操作

目录

知识点讲解

实际操作

一.向一个文本文件中写入数据:

 二.从一个文本文件中读取数据,并对读取的数据做简单处理。

 三.二进制文件的写入操作

 四.对二进制文件的读取操作

五. 举例

六.IO操作的简单应用(代码和举例都在更新和完善中)


知识点讲解

文件流:

C++在头文件fsream中定义了C++的文件流类体系,当程序中使用文件时,要包含头文件fstream.h

在涉及文本文件的操作时,将输入文件看成键盘,将输出文件看成显示器,格式不变;

只需要在程序中增加打开与关闭文件的语句

文本文件的打开与关闭:

在文件操作前,需要将程序与待操作的文件联系起来,使程序可以“引用”文件

在程序内定义一个文件类的对象,该对象与文件发生联系,

程序内所有与文件的操作都是对该对象的操作。

ifstream(输入流)定义用于输入的文件对象

ofstream(输出流)定义用于输出的文件对象

输入和输出是相对“内存”而言的。

fstream infile,outfile;//两个对象,可以联系两个输入输出文件;

ifstream infile;//对象只能联系输入文件;

ofstream outfile;//对象只能联系输出文件;

如何使文件类的对象与想要操作的文件发生联系?

用对象打开文件

ifstream infile;//定义输入文件类对象

infile.open("myfile.txt"t);//利用函数打开某一文件

//打开文件“myfile1.txt”用于输入,并将这个文件与输入文件类对象infile建立联系,

//今后用到这个文件“myfile1.txt”的地方就用infile来代替。

打开文件的作用是,使文件流对象与要使用的文件名之间建立联系

ofstream outfile;//定义输出文件类对象

outfile.open("myfile1.txt");//打开某一文件供输出

用完文件后,使用成员函数关闭文件,如:

ifsream infile;

ofstream outfile;

infile.open("myfile1.txt");

outfile.open("myfile2.txt");

double x,y;

infile>>x>>y;

outfile<<x<<"\t"<<y<<endl;

infile.close();

outfile.close();

当用类fsream定义文件对象时,该对象既能定义输入文件对象,又能定义输出文件对象,所以打开文件时必须在成员函数open()中的参数中给出打开方式(读或写)。

fstream infile,outfile;//定义了两个文件类对象

infile.open("file1.txt",ios::in);

outfile.open("file2.txt",ios:;out);

char ch;

infile>>ch;

outfile<<ch;

infile.close();

outfile.close();

打开文件后,要判断打开文件是否成功。如果打开成功,则文件流对象值为非零值;

如果打开失败,则值为0

fstream infile,outfile;

infile.open("file1.txt",ios::in);

outfile.open("file2.txt",ios:;out);

if(!infile)

{cout<<"不能打开输入文件"<<endl;exit(0);}

if(!outfile)

{cout<<"不能打开输出文件"<<endl;exit(0);}

打开输入文件时,文件必须存在,

打开输出文件时,如果文件不存在,则系统自动创建新文件,如果文件存在,则删除原文件中的内容,使其成为一个空文件。

二进制文件的读写操作:

若在文件的打开方式中没有特殊说明,打开的文件均为ASCII码文件,若要打开二进制文件,则要特别说明并用特定的读写函数。

fstream   infile,outfile;

infile.open(“inf1.dat”,  ios::in,  ios::binary);

outfile.open(“outf1.dat”,  ios::out,  ios::binary);

由于二进制文件中的数据不是ASCII码所以不能直接对其读写,必须要通过特定的函数予以转换。

输入函数:

infile.read( char  *,   int )

输入文件对象名(数据输入的内存地址,一次性读入的字节数)

地址要强制转换成字符指针型

int  i;

infile.read((char *)&i, sizeof(int));//从文件中输入1个整型数到i

int  a[10];

infile.read((char *)a,  10*sizeof(int));//从文件中输入10个整型数到a

输出函数:

outfile.write( char  *,   int );

int  i=4;

outfile.write((char *)&i, sizeof(int));//向文件输出一个整型数i

int  a[10]={0,1,2,3,4,5,6,7,8,9};

outfile.write((char *)a,  10*sizeof(int));//向文件输出一个整型数组a

判断二进制文件是否读到文件尾

infile.eof( )   

当到达文件结束位置时,该函数返回一个非零值;否则返回零。

fstream   infile;

infile.open(“data1.dat”,ios::in, ios::binary);

if(!infile)//判断打开是否出错

{   cout<<“Open Error!\n”;  exit(1);  }

char  str[300];

while(!infile.eof())//判断是否读到文件尾

     infile.read(str, 300);

实际操作

一.向一个文本文件中写入数据:

#include <iostream>
#include <fstream>//两个类的结合
//fstream是ifstream和ofstream的结合
//既包括了输入操作也包括输出操作
using namespace std;

int main()
{
	int a[5];
	//ofstream outfile("d:\\桌面\\0209实验.txt", ios::out);
		//d:\\表示d盘根目录
		//ios::out如果文件不存在,会按照定义的名称创建文件。
		//如果原来存在文件,会清空;如果不存在,创建
	ofstream outfile("d:\\桌面\\0209实验.txt", ios::app);
	//以输出方式打开,数据追加到文件末尾
	if (!outfile)
	{
		cout << "open error" << endl;
		return 0;
	}
	else
	{
		cout << "请输入数据" << endl;
		for (int i = 0; i < 5; i++)
		{
			cin >> a[i];
			outfile << a[i] << " ";
		}
	}
	outfile.close();//关闭文件输出流
	return 0;
}

 编译器运行结果:(例如我们输入1 2 3 4 5)

桌面上会自动创建一个txt文件。

txt文件会因为这段程序,而被写入1 2 3 4 5 这组数据,效果如下:

 

 二.从一个文本文件中读取数据,并对读取的数据做简单处理。

#include <iostream>
#include <fstream>//两个类的结合
//fstream是ifstream和ofstream的结合
//既包括了输入操作也包括输出操作
using namespace std;

int main()
{
	int a[20];
	int maxs = -1, index = 0;
	ifstream infile("d:\\桌面\\0209shiyan.txt", ios::in);
	if (!infile)
	{
		cout << "oper error" << endl;
		return 0;
	}
	else
	{
		for (int i = 0; i < 5; i++)
		{
			infile >> a[i];
			cout << a[i] << " ";
			if (a[i] > maxs)
			{
				maxs = a[i];
				index = i;
			}
		}
		cout << endl << "maxs is " << maxs << endl;
		cout << "pos is " << index << endl;
	}
	return 0;
}

编译器运行结果:

 

因为是读取“一”中写入的数据而没有对0209shiyan.txt这个文本文件中的数据做任何修改,因此文本文件中的数据不变。

 三.二进制文件的写入操作

#include <iostream>
#include <fstream>
using namespace std;
struct student
{
	string name;
	int age;
	char sex;
};
int main()
{
	student stu[3] = { "li",18,'F',"wu",19,'M',"zhang",17,'F' };
	ofstream outfile("d:\\桌面\\0209shiyan.txt",ios::out, ios::binary);
	//ios::binary 是“将数据转变为二进制的形式储存在文件中”的意思
	if (!outfile)
	{
		cout << "open error" << endl;
		exit(0);//代表终止所有程序的意思,和return 0; 功能类似
	}
	else
	{
		for (int i = 0; i < 3; i++)
		{
			outfile.write((char*)(&stu[i]), sizeof(stu[i]));
		}
		//write函数:write函数第一个参数必须是char*指针类型的数据,
		//如果不是这个类型的数据,需要进行强制转换
		//第二个参数是写入数据的大小。
		outfile.close();
		//关闭文件有终止缓冲区运行的作用,文本文件用完之后就要写close函数。
	}
	return 0;
}

 因为程序没有任何实质性的编译器层面的输出,所以编译器显示为0输出。

 由于是二进制的形式储存,所以文本文件执行显示层面展示的是一堆乱码,并且每次查看都不太一样。

 四.对二进制文件的读取操作

#include <iostream>
#include <fstream>
using namespace std;
struct student
{
	string name;
	int age;
	char sex;
};
int main()
{
	student stu[3];
	ifstream infile("d:\\桌面\\0209shiyan.txt", ios::out, ios::binary);
	if (!infile)
	{
		cout << "open error" << endl;
		exit(0);
	}
	else
	{
		for (int i = 0; i < 3; i++)
		{
			//outfile.write((char*)(&stu[i]), sizeof(stu[i]));
			infile.read((char*)&stu[i], sizeof(stu[i]));
		}
		//read函数:与write函数参数格式要求相同。
		//第一个参数 要求必须是char*类型的,第二个参数是读取数据的大小。
		infile.close();//infile用完了,就要close它。
		//上述代码实现的功能是将二进制文件从文件中读取出来,并储存在了程序的数组之中。
		//将程序中的数组存储的内容输出,看看读入的数据是否正确?
		for (int i = 0; i < 3; i++)
		{
			cout << "NO." << i + 1 << endl;
			cout << "name:" << stu[i].name << endl;
			cout << "age:" << stu[i].age << endl;
			cout << "sex:" << stu[i].sex << endl;
		}
	}
	return 0;
}

 运行效果:

发现读取到的数据和“三”中给文本文件写入的数据完全一致

由于本程序只涉及到“读取”操作,因此没有对0209shiyan.txt中的内容做任何修改。

五. 举例

从编译器的运行框中输入一串字符串,挑出其中属于字母的字符,在编译器运行框中输出的同时,将输出结果也储存在一个文本文档中;读取该文本文档中的数据,并将所有小写字母都转化为大写字母,将运行结果储存在另一个文本文档中。

#include <iostream>
#include <fstream>
#include <cstring>
using namespace std;
void save_to_file()
{
	ofstream outfile("d:\\桌面\\0209shiyan.txt", ios::out);
	//如果不指定位置,不同编译器存储txt文件的位置不同。
	if (!outfile)
	{
		cout << "open error" << endl;
		exit(0);
	}
	else
	{
		char a[1000];
		cin.getline(a, 1000, '\n');
		for (int i = 0; i < strlen(a); i++)
			if (a[i] >= 'a' && a[i] <= 'z' || a[i] >= 'A' && a[i] <= 'Z')
			{
				outfile.put(a[i]);
				//outfile.put函数:将一个参数携带的数据传入到文本文件中并储存
				cout << a[i] << " ";//同时将数据送达显示器
			}
		cout << endl;
		outfile.close();
	}
}
void get_from_file()
{
	ifstream infile("d:\\桌面\\0209shiyan.txt", ios::in);//从0209shiyan.txt中读入数据
	ofstream outfile("d:\\桌面\\0209shiyan1.txt", ios::out);//将结果的数据传出,写到0209shiyan1.txt中
	if (!infile||!outfile)
	{
		cout << "open error" << endl;
		exit(0);
	}
	else
	{
		char ch;
		while (infile.get(ch))
		{
			if (ch >= 'a' && ch <= 'z')
			{
				ch -= 32;//将小写字母转化为大写字母
				outfile.put(ch);//储存。
			}
		}
		infile.close();
		outfile.close();
	}
}
int main()
{
	save_to_file();
	get_from_file();
	return 0;
}

运行结果:

 

 文本文档中的效果:

程序使得计算机自主创建了一个文本文档,被我命名为0209shiyan1.txt。

在0209shiyan.txt中

效果是这样的:

在0209shiyan1.txt中,效果是这样的:

六.IO操作的简单应用(代码和举例都在更新和完善中)

        一.对《06笔记 输入输出流重载》中代码补充IO操作:

#include <iostream>
#include<fstream>
using namespace std;
class complex
{
private:
	double real,imag;
public:
	complex() { real = 0; imag = 0; }
	complex(double a, double b) { real = a; imag = b; }
	complex operator + (complex&);
	void showcomplex(){ cout << "(" << real << "," << imag << "i)" << endl; }
	//friend complex operator +(complex&, complex&);
	friend istream& operator>>(istream&, complex&);//输入流重载的声明
	friend ostream& operator<<(ostream&, complex&);//输出流重载的声明

};
inline complex complex::operator+(complex& a)
//函数的返回值类型 上一级::下一级 运算符(数据类型 变量名称)
{
	complex c;
	c.real = this->real + a.real;
	c.imag = this->imag + a.imag;
	return c;
}
//写法2
/*
complex operator + (complex& a, complex& b)
{
	complex c;
	c.real = a.real + b.real;
	c.imag = a.imag + b.imag;
	return c;
}
*/
//输入流重载
//istream 输入流 ostream 输出流
istream& operator >>(istream &input, complex& c)
{
	cout << "请分别输入一个复数的实部和虚部:" << endl;
	input >> c.real >> c.imag;
	return input;
}
//输出流重载
ostream& operator<<(ostream& output, complex& c)
{
	output << "(" << c.real << "," << c.imag << "i)" << endl;
	return output;
}

int main()
{
	
	ofstream outfile("d:\\桌面\\complex.txt", ios::out);
	ifstream infile("d:\\桌面\\zhengshu.txt", ios::in);
    //声明:只有ostream才可以自主创建新的文本文件,
    //istream不能,需要用户提前创建并命名,并事先写入数据
	complex a, b, c;
	infile>> a >> b;
	c = a + b;
	//infile.close();
	a.showcomplex();
	b.showcomplex();
	c.showcomplex();
	cout << c; 
	outfile << a << endl;
	outfile << b << endl;
	outfile << c << endl;
	infile.close();
	outfile.close();
	return 0;
}



 声明:

    //声明:只有ostream才可以自主创建新的文本文件,
    //istream不能,需要用户提前创建并命名,并事先写入数据

实现部分:

 由上述声明,笔者自行创建了一个文本文件叫做zhengshu.txt,写入数据 1 2 3 4

效果如下:

 现在对原代码进行编译,运行效果为:

 此时,文本文件complex.txt中的效果如下:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

青山入墨雨如画

你的鼓励将是我创作的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值