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”);//等价的 ***
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.两个函数 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语句链接起来 * 在程序运行中发现:如果不编写填充,它默认填充空白