码迷,mamicode.com
首页 > 其他好文 > 详细

文件的输入和输出

时间:2015-05-25 00:54:25      阅读:278      评论:0      收藏:0      [点我收藏+]

标签:

文件的输入和输出

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来记录的。

我们先来了解:检查试图打开文件时是否成功打开:isopen()函数 if(!fin.isopen())//文件打开失败 { ………… }

  • 这中方式可以检测出一些微妙的问题:试图以不合适的文件模式打开文件时失败

文件模式

  • 文件模式描述的是:文件将如何被使用:读,写,追加等等。

问题:如何向文件中输入数据,但保证文件原内容不被删除


/创建对象,关联文件
	//如果不想原有数据被删除,必须注意第二参数的使用
	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. iosbase::app
  2. iosbase::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.isopen())
{
	cout<<file<<"当前的数据是:"<<endl;
	while(fin.get(ch))
	  cout<<ch;
	fin.close();
}
//向文件中增加数据
ofstream fout(file,iosbase::out|ios_base::app);
if(!fout.isopen())
{
	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<<<right; 创建对象="" ifstream="" fin;="" fin.open(file,ios_base::in|ios_base::binary);="" read读取="" while(fin.read(="" (char*)&pl,="" sizeof="" pl))="" {="" 不清楚是什么意思?会不会是输出格式化="" cout=""><<setw(20)><<<": "
			<<setprecision(0)><<setw(12)><<<setprecision(2)><<setw(6)><<<endl; }="" 切断联系,关闭文件="" fin.close();="" 增加数据到新的文件中="" 创建对象="" ofstream="" fout(file,ios_base::out|ios_base::app|ios_base::binary);="" 判断文件打开是否成功="" if(!fout.is_open())="" {="" cout=""><<<"file 打开失败\n";
		//终止程序
		exit(1);
	}

	//数据读入
	cout<<"请输入行星的名字(输入空行停止)\n";
	cin.get(pl.name,20);
	//判断字符串第一个不是空
	while(pl.name[0] != ‘\0‘)
	{
		//调用了一个函数
		eatline();
		cout<<"请输入行星的人口:\n";
		cin>>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<<<"文件当前的内容是:\n";
		while(fin.read((char*)&pl,sizeof pl))
		{
			cout<<setw(20)><<<": "
			<<setprecision(0)><<setw(12)><<<setprecision(2)><<setw(6)><<<endl; }="" 文件关闭="" fin.close();="" return="" 0;="">

程序的几个说明:
(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语句链接起来
  • 在程序运行中发现:如果不编写填充,它默认填充空白

文件的输入和输出

标签:

原文地址:http://www.cnblogs.com/rupengkun/p/4526877.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!