I/O
1.概念部分
助记:
A输入流/输入文件:指A作为B的输入源,ifstream>>
B输出流/输出文件:指B作为A的输出地,ofstrem<<
1.编译系统已经以运算符或函数的形式做好了对标准外设(键盘、屏幕、打印机、文件)的接口,使用时只需按照要求的格式调用即可
2.C++语言的I/O系统向用户提供一个统一的接口,使得程序的设计尽量与所访问的具体设备无关,在用户与设备之间提供了一个抽象的界面:输入输出流。
3.用标准流进行输入/输出时,系统自动地完成数据类型的转换。对于输入流,要将输入的字符序列形式的数据变换成计算机内部形式的数据(二进制或ASCII)后,再赋给变量,变换后的格式由变量的类型确定。
4.对于输出流,将要输出的数据变换成字符串形式后,送到输出流(文件)中。
2.友元重载输入输出运算符
1.对象是不能直接输入输出的
ClassName a;
cin>>a;非法
cout<<a;非法
2.将重载这二个运算符的函数说明为该类的友元函数,返回值类型:类istream的引用,若是输出流就都改成ostream
class classNmale{
public:
friend istream & operater >>(istream &, ClassName &);
}
istream &operater >>(istream &i, ClassName &j){
return i;//返回输入流的引用
}
cin>>a;相当于
operator>>(cin,a);
3.cin中可以连续使用运算符“>>”
cin>>a>>b;相当于
operator>>(cin,a);
operator>>(cin,b);
第一个参数:是“>>”的左操作数cin类型,类istream的引用
第二个参数:是“>>”的右操作数,即欲输入的对象的引用.
3.文件流
1.当使用文件时,在程序头有:#include<fstream.h>
其中定义了各种文件操作运算符及函数。
2.程序对文本文件的操作与对键盘、显示器的操作比较:
在涉及文本文件的操作时,将输入文件看成键盘,将输出文件看成显示器,格式不变。只需在程序中增加打开与关闭文件的语句。
这里的输入文件:意思其实是指从文件中取数据到内存中
输出文件:是指内存中数据输出到文件中
3.文件操作:
4.在文件操作前,需要将程序与被操作的文件联系起来,使程序可以“引用”文件。在程序内定义一个文件类的对象,由该对象与文件发生联系,程序内所有的与文件的操作都是对该对象的操作
fstream infile , outfile;可以联系输入输出文件
ifstream infile;对象只能联系输入文件
ofstream outfile;对象只能联系输出文件
5.打开文件的作用是,使文件流对象与要使用的文件名之间建立联系
6.打开文件“myfile1.txt”用于输入,并将这个文件与输入文件类对象infile建立联系,今后,在程序中,用到这个文件“myfile1.txt”的地方就用infile来代替
ifstream infile; 定义输入文件类对象
法一:infile.open(“myfile1.txt”);利用函数打开某一文件
法二:ifstream infile(“myfile1.txt”);创建时打开
7.打开文件“myfile2.txt”用于输出,并将这个文件与输出文件类对象outfile建立联系,今后,在程序中,用到这个文件“myfile2.txt”的地方就用outfile来代替。
ofstream outfile; 定义输出文件类对象
outfile.open(“myfile1.txt”);打开某一输出文件
8.将文件类对象看成键盘和显示器即可
ifstream infile; //定义输出文件类对象
infile.open(“myfile2.txt”);//利用函数打开某一文件
infile>>x‘\t’>>y;
ofstream outfile; //定义输入文件类对象
outfile.open(“myfile1.txt”);//利用函数打开某一文件
float x=3 , y=4;
outfile<<x<<y;
9.关闭文件
infile.close();
outfile.close();
10.小例
10.当用类fstream定义文件对象时,该对象即能定义输入文件对象,又能定义输出文件对象,所以打开文件时,必须在成员函数open()中的参数中给出打开方式(读或写)
fstream f1,f2;
f1.open("file1.txt", ios::in);
f2.open("file2.txt", ios::out);
fstream f1("file1.txt", ios::in|ios::out|ios::binary);
//ios::binary指二进制打开
11.判断文件是否打开:在打开文件后,都要判断打开是否成功。若打开成功,则文件流对象值为非零值;若打开不成功,则其值为0。
pfile1.open(“file1.txt”, ios::in);
if (!pfile1)
12.打开输入文件时:文件必须存在。
打开输出文件时:
若文件不存在,则建立文件;
若文件存在,则删除原文件的内容,使其成为一个空文件。
3.1 字符串的文件读写:
1.从文件输入一字符或一行字符,当输入至文件尾时,函数返回值为0,可以据此来判断循环结束
char ch, str[300];
从键盘/屏幕获得一个字符:cin.get(ch);
从文件中取一个字符输出:infile.get(ch);
向显示器输出一个字符:cout.put(ch);
向文件输入/写入一个字符:outfile.put(ch);相当于outfile>>ch
从键盘输入一行字符:cin.getline(str,300);
从文件输入一行字符:infile.getline(ch,300);
2.实现两文件的拷贝的程序
3.2 二进制文件的读写操作
1.若在文件的打开方式中没有特别说明,打开的文件均为ASCII码文件,若要打开二进制文件,则要特别说明并用特定的读写函数。
2.由于二进制文件中的数据不是ASCII码,故不能直接对其读写,必须要通过特定的函数予以转换
3.判断二进制文件是否读到文件尾
infile.eof( )
当到达文件结束位置时,该函数返回一个非零值;否则返回零。
if(!infile) 判断打开是否出错
while(!infile.eof()) 判断是否读到文件尾
infile.read(str, 300);
char buff[4096];
while (!infile.eof()){ 文件不结束,继续循环
infile.read(buff,4096); 一次读4096个字节
n=infile.gcount(); 取实际读的字节数
outfile.write(buff,n); 按实际读的字节数写入文件
}
3.3 文件指针
1.当一打开文件,文件指针位于文件头,并随着读写字节数的多少顺序移动
2.可以利用成员函数随机移动文件指针
f1.seekg(20*sizeof(int));
将文件指针移到第20个整数的位置
———————————————
输入输出
1)三种类别
1.对系统指定的标准设备的输入输出,即标准I/O。(键盘–屏幕)
2.以外存为对象进行输入输出,即文件I/O。(磁盘)
3.以内存为对象输入输出,即串I/O。(字符数组)
2)printf与scanf 弊端
1.printf 如果将浮点数a,以 %d 整型输出则会缺失精度。
2.scanf(%d, i)缺了& 还是可以运行。
而C++则会在编译时候对数据类型严格检查,类型错误则不可能通过编译。所以C++是类型安全的
C++引入对象,自然引入面向对象的输入输出系统,I/O类库,且具有可扩展性
3)流
1.数据从一处流到另一处的过程,叫流
2.或者说缓冲区中的数据就是流
4)iostream的四种流对象:cin、cout、cerr、clog
cout<<"C++";
相当于
cout.operator<<("C++");
cerr
1.是标准错误流。被指定为与显示器关联。
2.作用:向标准错误设备输出有关出错的信息
3.与cout的区别:cout可以输出到屏幕,也可以被重新定义输出到磁盘文件;而cerr只能输出到屏幕;
求一元二次方程:ax²+bx+c=0 的解
#include<iostream>
#include<cmath>
using namespace std;
int main(){
float a,b,c,disc;
cin>>a>>b>>c;
if(a==0)
cerr<<"分母不能为零"<,endl;
else
if((disc=b*b-4*a*c)<0)
cerr<<"没有实根"<<endl;
else
cout<<"x1="<<(-b+sqrt(disc)/(2*a))<<endl;
cout<<"x2="<<(-b+sqrt(disc)/(2*a))<<endl;}
clog
1.也是标准错误流
2.作用:与cerr相同
3.区别:cerr是不经过缓冲区的,而clog是要经过缓冲区的
5)输出流的格式函数(410页)
控制符
1:skipws
在标准流中skipws已经是默认开启状态。
skipws会忽略空白字符,包括空格,制表符(\t),换行符(\n)等不可见字符。
例:cin>>(这里空了很多空格) a; 此时的skipws 就发挥作用了
如果系统当前skipws开关已经关闭,那么可以在输入流中,插入skipws来打开。
stream<<setiosflags(ios::skipws);
2:left,rgith,internal,setw(使用控制符要包含iomanip.h)
left 制定域宽左对齐,right右对齐,internal 符号左对齐,数值右对齐
例: a=10; cout<<setw(6)<<setiosflags(ios::internal)<<a; 结合域宽控制符比较显而易见
setw()设置域宽
setfill(字符)设置一什么字符填充
cout<<setfill(’*’)<<setw(6)<<a; 结果:****10
3:showbase,hex,oct,dec,uppercase
hex 十六进制(不用调用setiosflags)
oct 八进制
dec 十进制
showbase 系统默认不设置
作用:在数值前面显示基指示符:十进制没有,八进制为 0,十六进制为 0x
a=10;
cout<<setiosflags(ios::showbase)<<hex<<a;
结果:0xa
uppercase:使得十六进制的的字符大写输出
4,showpoint,showpos,setprecision( n)
showpoint 强制输出带有小数和小数尾部无效数字0,如a=10.00;
例: cout<<setiosflags(ios::showpoint)<<a; 结果:10.0000(没指定,默认六位)
showpos 强制显示正数符号
例:cout<<setiosflags(ios::showpos)<< a; 结果:+10
setprecision( n); 从第几位数精确
例: a = 10.456;
cout<<setprecision(4)<<a;
结果:10.46