流(flow)
流向程序,称为输入流(input stream),流出程序,称为输出流(output stream).
在程序中使用include指令包含头文件<iostream>,可以用cin表示链接到键盘的输入流,用cout表示连接到屏幕的输出流,
文件I/O
程序从文件获得输入,称为读取文件;将输出发送给文件,称为写入文件。要将流连接到文件,必须像声明其他任何变量那样声明流,“输入文件流”的变量的类型名称是ifstream ;“输出文件流”的变量的类型名称是ofstream ; ifstream , ofstream类型在头文件为fstream的库中定义。
流变量必须连接到一个文件,这称为打开文件,用open函数完成操作。声明好输入流,并用open函数将其连接到文件,程序就可以用提取符>>从文件获取输入。
针对ofstream类型的一个流,成员函数open会新建一个尚不存在的输出文件,如输出文件存在,成员函数open会丢弃文件内容,所以在调用open函数后,输出文件为空。一旦调用open函数就可以使用插入操作符<<将输出发送到那个文件当中。
#include<fstream>
using namespace std;
ifstream instream;
instream.open("infile.dat");
int onenumber , anothernumber;
instream >>onenumber>>anothernumber ;
ofstream outstream ;
outstream.open("outfile.dat");
outstream<<"onenumber ="<<onenumber<<"anothernumber = "<<anothernumber ;
一个文件两个名称
程序使用的每个输入和输出文件都有两个名称,外部文件名是文件真实名称,但是在open函数调用使用一次,该函数将文件连接到一个流,一旦调用了open,就必须将流名称作为文件名使用。
调用close()函数关闭文件,好习惯是每次使用文件后都调用close函数,原因其一:只要在程序正常终止的前提下,系统才会为你关闭文件,如果异常终止,文件就不会关闭,并可能损坏。其二:你可能希望程序将输出发送给一个文件,以后又将那些输出读回程序。
fail()函数:
fail函数测试一个流操作是否失败。ifstream ,ofstream类都有一个名为fail的成员函数,fail函数不取任何参数,返回一个bool值。
追加到文件:
要将数据追加到文件尾,使其位于原有内容之后,应该像下面这样打开文件
语法:
outputstream.open(Filename ,ios:;app);示例:
ofstream outputstream;
outstream.open("impertant.txt" ,ios::app);
文件名作为输入:
在运行多个文件的操作的时候,频繁使用Open函数会比较麻烦,将文件名作为输入会减少此类麻烦,程序读入文件名必须有一个能保存字符串值的变量,,一旦将文件名输入字符串变量,就可将该字符串变量用作成员函数open的实参。
ifstream instream;
instream.open(filename);
if(instream.fail())//用成员函数fail核实文件是否成功打开
{
cout<<"input file opening filed.\n";
exit(1);
}
流I/O工具
用流函数格式化输出
对程序输出的布局进行调整称为对输出进行格式化。
precision函数
是类ofstream的成员函数,一旦执行了precision函数,从此以后,向那个流输出带小数点的任何数字时,要么总共保留两个有效数字,要么在小数点之后保留两位--具体由编译器决定。
setf函数
setf 是set flags的缩写,flag(标志)是以二选一的方式来做一件事情的指令。
关于setf的详细(可以看这位博主的文章)
操纵元
是以非传统方式调用的函数,调用操纵元后,它本身又会调用应该成员函数,操纵元位于插入操作符<<之后,好似它本身就是下一个要输出的项,和传统函数一样,操纵元可以有,也可以没有参数(endl就是)。
操纵元setw和船员函数width所做的事情完全一样,可以用不通域宽输出数字。
操纵元setprecision与成员函数precision所做的事情完全一样。
要使用setw或setprecision操纵元,必须包含#include<iomanip>预编译指令还有using namespace std;
流作为函数实参
流参数必须传引用。
字符I/O
get和put成员函数
成员函数get
每个输入流都有名为get的成员函数,它读取一个输入字符。和提取操作符不同,无论下一个输入字符是声明,get都会读取。具体地说,无论下个输入字符是空白字符(空格,制表符),还是换行符,get都会读取它,get函数获取char类型的变量作为参数。调用get时,会读取下一个输入字符,并把实参变量设为该字符。
char next;
cin.get(next);//从键盘输入下一个字符,并保存到变量nect中。
//要用文件流的话
instream.get(next);
‘\n' 与"\n"
表面上区别不大,但是在任何情况下都不可以互换,'\n'是char类型的值,可存储到char类型的变量当中,"\n"是字符串,凑巧只有一个字符,不属于char类型,不能存储到char类型的变量中。
可以用成员函数get检查行尾,一下循环一行输入,并在传入换行符'\n'后终止。然后后续所有输入都将从下一行的开头读取,所以只是简单的回显了输入,但可以用同样的技术对输入进行其他出任何处理。
cout<<"Enter a line of input and i will echo it.\n" ;
char symbol ;
do
{
cin.get(symbol);
cout<<symbol;
}while(symbol != 0);
cout<<"That is all for this demonstreation";
成员函数put
每个输出流都有名为Put的成员函数,它获取一个char类型的参数。调用成员函数Put后,它的参数的中被输出到输出流。
要用到输出流使用Put函数之前,程序必须先调用open函数将流连接到输出文件。
outputstream.put(char_expression)//语法
putback函数
有时需要知道输入流中的下一个字符,但是读取了下一个字符之后,发现自己不想处理该字符,所以想把它重新放回输入流,标准输入流cin需要掌握的函数(详情可以参考这位博主的)
//检查输入
//演示newline()函数和getint()函数
#include<iostream>
using namespace std;
void newline();
//丢弃当前输入行上剩余的所有输入
//同时丢弃行末的'\n'
//只支持键盘输入
void getint(int &number);
//后条件:为number变量
//赋一个由用户核审的值
int main()
{
int n;
getint(n);
cout<<"dinal value read in = "<<n<<endl;
<<"End of demonstration.\n";
void newline()
{
char symbol;
do
{
cin.get(symbol);
}while(symbol != '\n');
void getint(int &number)
{
char ans;
do
{
cout<<"Enter input number :";
cin>>number;
cout<<"you entered"<<number
<<"is that coreect?(yes / no):";
cin>>ans;
newline();
}while((ans !='Y') && (ans != 'y'));
}
可以在一个程序中使用newline的两个版本:一个无参数,一个获取istream参数。
eof成员函数
每个输入文件流都有名为eof的成员函数,用于判断何时读完文件的全部内容,没有更多的输入。时判断程序是都读完全部内容的第二种方法。
可以用来控制while循环,do-while循环,if-else语句的布尔表达式。如果程序已经越过输入文件的末尾,表达式将得到满足(true),否则false。
由于通常只想测试是否没有抵达文件尾,在待用成员函数eof的时候,通常在它的前面用!来操作。
if(!fi.eof())
cout<<"not done yet.";
else
cout<<"End of the title.";
while循环使用成员函数get从输入文件将每个字符读入char类型的next变量,并将它们一一输出到屏幕,程序越过文件为之后,instream.eof()的值从false变成true。循环终止。
instream.get(next)
while(! instream.oef())
{
cout<<next;
instream.get(next);
}