文件的输入和输出

文件的输入和输出

1.程序写入文件 ,应遵循以下规则 (1)创建一个ofstream对象来管理输出流 (2)将对象和输出流关联起来 (3)以使用cout的方式来使用该对象。 例如:

ofstream fout ;         //创建对象  

fout.open(“jar.txt”) ;  //关联文件

注意: * Ofstream fout (“jar.txt”) ;//跟上面的两条语句是等效的那么关于第三点:使用cout的方式来使用该对象,比如: * fout << “ I love you !”; 原因:fout对象的类型是ofstream,他的基类是ostream,我们知道,派生类的对象是可以使用基类的方法的。 警告: 以这种方式来进行文件的输出时,如果不存在这个文件,程序会创建并输出,但是如果是已有文件。程序会清空并进行数据的输出。(后面有关于如何打开已有文件,并保留其内容) 测试:测试成功 我们进入下一个内容:文件的读取 (1)创建一个ifstream对象来管理输入流 (2)将这个对象和特定的文件关联 (3)以使用cin的方式使用该对象 例如:

Ifstream fin;            //创建对象  

in.open(“test.txt”);  //关联文件

* 上述两条语句合并为一条是:ifstream fin(“test.txt”);//等价的 ***

流状态的检查和is_open( )函数

C++流文件类从ios_base类那里继承了一个“流状态成员”流状态成员:存储了指出流状态的信息。比如说: 一切顺利,达到了文件尾,I/O操作失败等等,通常来说,如果一切正常,那么流状态就会为0,其他的情况都是通过将特定位设置为1来记录的。 我们先来了解:检查试图打开文件时是否成功打开:is_open()函数 if(!fin.is_open())//文件打开失败 { ………… } * 这中方式可以检测出一些微妙的问题:试图以不合适的文件模式打开文件时失败

文件模式

  * 文件模式描述的是:文件将如何被使用:读,写,追加等等。 问题:如何向文件中输入数据,但保证文件原内容不被删除



/创建对象,关联文件

	//如果不想原有数据被删除,必须注意第二参数的使用

	ofstream fout("qwe.txt",ios_base::out|ios_base::app);

	if(!fout.is_open())

		cout<<"文件打开失败!";

	else

		fout<<"我叫茹鹏锟,来自西安建筑科技大学";

说明:上述语句使用|运算符来合并模式,`ios_base::out|ios_base::app`意味着启用模式out和app。 注意:在文件模式常量中:

  1. ios_base::app
  2. ios_base::ate

这两个的含义都是将文件指针指向打开的文件尾。

追加文件

补充:1.两个函数 exit() 功能:关闭所有文件,终止正在进行的程序 头文件:stdlib.h 2.EXIT_FAILURE

EXIT_FAILURE是C语言头文件库中定义的一个符号常量,

在vc++6.0下头文件stdlib.h中定义如下:#define EXIT_FAILURE 1



EXIT_FAILURE 可以作为exit()的参数来使用,表示没有成功地执行一个程序。

EXIT_SUCCESS 作为exit()的参数来使用,表示成功地执行一个程序。

我们来看一个程序实例

using namespace std;

//定义一个字符串指针,内容是"guest.txt"

const char* file = "guest.txt";

int main()

{

char ch;

//创建对象

ifstream fin;

//关联对象

fin.open(file);

//检查打开

if(fin.is_open())

{

	cout<<file<<"当前的数据是:"<<endl;

	while(fin.get(ch))

	  cout<<ch;

	fin.close();

}

//向文件中增加数据

ofstream fout(file,ios_base::out|ios_base::app);

if(!fout.is_open())

{

	cerr<<"can't open"<<file<<"file for output.\n";

	//终止程序,程序就结束了

	//不会再执行下面的内容了

	exit(1);

}

cout<<"输入客户的名字(如果读到空行就停止):\n";

string name;

while(getline(cin,name) && name.size()>0)

{

	fout<<name<<endl;

}

fout.close();

//输出结果的显示

fin.clear();

fin.open(file);  

if(fin.is_open())  

{

	cout<<file<<"文件的当前内容是:\n";  

	while(fin.get(ch))  

	  cout<<ch;  

	fin.close();  

}

return 0;

}

关于程序的几点说明: 1.exit(1)会终止程序的进行,不再执行后面的代码部分 2.第一次运行是无法打开文件的: * 因为新文件还没有被创建 3.在追加文件后,显示文本当前文本内容的时候,记得加入函数 * fin.clear();



//这个是做什么的

inline void eatline(){while(std::cin.get() != 'a') continue;}

//结构体类型

struct planet

{

	char name[20];

	double population;

	double g;

};

//一个指向char类型的字符串指针

const char* file="planets.dat";



int main()

{

	using namespace std;

	planet pl;

	//这个是干嘛的?

	cout<<fixed<<right;

	//创建对象

	ifstream fin;

	fin.open(file,ios_base::in|ios_base::binary);

	//read读取

	while(fin.read( (char*)&pl, sizeof pl))

	{

		//不清楚是什么意思?会不会是输出格式化

		cout<<setw(20)<<pl.name<<": "

			<<setprecision(0)<<setw(12)<>pl.population;

		cout<<"请输入行星的重力加速度\n";

		cin>>pl.g;

		//为什么又要调用这个函数

		eatline();

		//二进制文本输入

		fout.write((char*)&pl, sizeof pl);

		cout<<"请输入行星的名字(输入空行表示停止):\n";

		cin.get(pl.name,20);

	}

	//切断联系:文件关闭

	fout.close();

	//二进制文件的显示

	//估计只有我的电脑需要清空一下吧

	fin.clear();

	//关联变量

	fin.open(file,ios_base::in|ios_base::binary);

	//判断文件的打开

	if(fin.is_open())

	{

		cout<<file<<"文件当前的内容是:\n";

		while(fin.read((char*)&pl,sizeof pl))

		{

			cout<<setw(20)<<pl.name<<": "

			<<setprecision(0)<<setw(12)<

程序的几个说明: (1)为什么在返回值类型前面加上inline

在定义函数时,在返回值类型前加上inline表示把这个函数定义为内联函数。

此类函数在编程过程中将在调用处将函数展开(就像处理#define宏一样),

从而避免像普通函数一样去调用,以节省程序执行开销,提高运行效率。

* 重点:节省可程序的开销,提高了运行效率(不用去调用了) (2)`inline void eatline(){while(std::cin.get() != 'a') continue;}`这个内联函数有什么作用

其实`\n`比较不好理解,我们可以换一个字符`a`那么在程序运行时我们就会发现,

只有当这个函数检测到字符a,他才会跳出这个内联函数的循环,这个内联函数的作用说白了,就是为了

检测设定的字符

* 还有一点问题:为什么 去掉之后,就不能多次输入数据了

关于这一点书中给了明确的解释:

这条内联函数会导致程序读取并丢弃包括换行符的内容,在他之后是cin.get(pl.name,20);

如果保留了换行符,那么这条语句就会将换行符做空行读取,从而终止操作

(3)关于语句`cout<<fixed<<right;`的意思是什么? 右对齐和定点选项 c++在头文件iomanip中提供了一些控制符,十分的方便,其实,最长用的也就是下面这三个   * setprecision() 设置精度 * setfill()填充字符 * setw()字段宽度 他们三个参数的情况说明: setprecision()控制符接受一个控制精度的整型参数,setfill()控制符接受一个指向指定的char类型的参数,setw()控制符接受一个指定字段宽度的整型参数。 * 因为都是控制符,所以可以用cout语句链接起来 * 在程序运行中发现:如果不编写填充,它默认填充空白

你可能感兴趣的:(文件)