1、流的控制
????iomanip ? ? ? ? ?在使用格式化I/O時應包含此頭文件。
????stdiostream ? 用于混合使用C和C + +的I/O機制時,例如想將C程序轉變為C++程序
2、類繼承關系
ios是抽象基類,由它派生出istream類和ostream類, iostream類支持輸入輸出操作,iostream類是從istream類和ostream類通過多重繼承而派生的類
類ifstream繼承了類istream,類ofstream繼承了類ostream,類fstream繼承了 類iostream
iostream頭文件中4種流對象
對象 | 含義 | 對應設備 | 對應的類 | c語言中相應的標準文件 |
cin | 標準輸入流 | 鍵盤 | istream_withassign | stdin |
cout | 標準輸出流 | 屏幕 | ostream_withassign | stdout |
cerr | 標準錯誤流 | 屏幕 | ostream_withassign | stderr |
clog | 標準錯誤流 | 屏幕 | ostream_withassign | stderr |
cout補充
1、用“cout<<”輸出基本類型的數據時,可以不必考慮數據是什么類型,系統會判斷數據的類型
??????并根據其類型選擇調用與之匹配的運算符重載函數。這個過程都是自動的,用戶不必干預。
????????如果在C語言中用prinf函數輸出不同類型的數據,必須分別指定相應的輸出格式符,十分麻煩,而且容易出錯
2、cout流在內存中對應開辟了一個緩沖區,用來存放流中的數據,當向cout流插 人一個endl時,
?????不論緩沖區是否已滿,都立即輸出流中所有數據,然后插入一個換行符, 并刷新流(清空緩沖區)。
????????注意如果插人一個換行符”\n“(如cout<<a<<"\n"),則只輸出和換行,而不刷新cout 流(但并不是所有編譯系統都體現出這一區別)。
3、在iostream中只對"<<"和">>"運算符用于標準類型數據的輸入輸出進行了重載,但未對用戶聲明的類型數據的輸入輸出 進行重載。
????如果用戶聲明了新的類型,并希望用"<<"和">>"運算符對其進行輸入輸出,按照重運算符重載來做。
cout 流通常是傳送到顯示器輸出,但也可以被重定向 輸出到磁盤文件,而cerr流中的信息只能在顯示器輸出
cerr是不經過緩沖區,直接向顯示器上輸出有關信息,而clog中的信息存放在緩沖區中,緩沖區滿后或遇endl時向顯示器輸出
3、標準輸入流?cin
????重點掌握的函數
?? ?cin.get()???????????????? //讀入一個字符并返回它的值
?? ?cin.get(一個參數) ?//讀入一個字符并把它存儲在ch?
?? ?cin.get(兩個參數) ?//可以讀取字符串
?? ?cin.get(三個參數) ?//可以讀字符串?? ??? ?
?? ?cin.getline()
?? ?cin.ignore()?? ?????? ?//讀取字符并忽略指定字符
?? ?cin.peek()?? ?????? ? //檢查下一個輸入的字符,不會把字符從流中移除
?? ?cin.putback()????? ?//返回一個字符給一個流
重要
1、使用cin,從流中讀出的字符,流中就沒有這字符了,再次讀取時只能讀取剩下的
2、緩沖去只有在遇到EOF、手動敲回車、流(緩存區)滿時,才將流中的字符全部讀出(即清空緩存區)
練習
1、從流中取一個字符,然后在放進去;
2、判斷流中的第一個字符是不是放進去的那個字符;
3、從流中讀取10個字符;
4、從流中忽略5個字符,再讀取10個字符;
5、最后讀取剩下的字符,最后輸出讀到的所有字符
#include <iostream>
using namespace std;int main()
{char ch1;int look;char str1[11] = {0};char str2[11] = {0};char str3[100] = {0};//從流中取一個字符,然后在放進去ch1 = cin.get();cin.putback(ch1);//判斷流中的第一個字符是不是放進去的那個字符look = cin.peek();if(look == (int)ch1){cout<<"cin.peek()放進去的字符在第一個位置"<<endl;}else{cout<<"cin.peek()放進去的字符不是在第一個位置"<<endl;}//從流中讀取10個字符cin.get(str1,11);//從流中忽略5個字符,再讀取10個字符cin.ignore(5);cin.get(str2,11,EOF);//最后讀取剩下的字符,最后輸出讀到的所有字符cin.getline(str3,100);//輸出讀到的數據cout<<"第一個字符"<<ch1<<endl;cout<<"第一組 字符串:"<<str1<<endl;cout<<"第二組 字符串:"<<str2<<endl;cout<<"剩下的字符串:"<<str3<<endl;system("pause");return 0;
}
輸出:
0123456789abcde9876543210zzzzzzzzzzxxxxxxxxxxxxxyyyyyyyyyyyy
cin.peek()放進去的字符在第一個位置
第一個字符0
第一組 字符串:0123456789
第二組 字符串:9876543210
剩下的字符串:zzzzzzzzzzxxxxxxxxxxxxxyyyyyyyyyyyy
4、標準輸出流 cout
? 流成員函數
??cout.flush() ?????//清空緩沖區
??cout.put()?? ?????//把字符寫入流中
??cout.write()?? ???//將字符串寫入當前輸出流中
? eg : cout.setf( ios::dec );
????? ? ?cout.setf(ios::hex,ios::basefield);【建議使用這種】
? 需注意:1、fmtflags setf( fmtflags flags ); 使用這種,一定要先取消當前基【cout.unself()】,之后才可以設置新的基
?2、fmtflags setf( fmtflags flags, fmtflags needed ); 使用這種,第二個參數設為當前的基,或者當不知道當前基時,設為ios_base::basefield清除當前的所有可能的基?? ?
??控制符,頭文件<iomanip>
?eg: ?cout<<setw(5);
5、文件I/O
由于文件設備并不像顯示器屏幕與鍵盤那樣是標準默認設備,不能像cout那樣預先定義的全局對象,所以我們必須自己定義一個該類的對象。
ifstream類,它是從istream類派生的,用來支持從磁盤文件的輸入。
ofstream類,它是從ostream類派生的,用來支持向磁盤文件的輸出。
fstream類,它是從iostream類派生的,用來支持對磁盤文件的輸入輸出。
文件原理
????文件打開都有一個文件指針,該指針的初始位置由I/O方式指定,每次讀寫都從文件指針的當前位置開始。每讀入一個字節,指針就后移一個字節。當文件指針移到最后,就會遇到文件結束EOF(文件結束符也占一個字節,其值為-1),此時流對象的成員函數eof的值為非0值(一般設為1),表示文件結束 了。
? ? 文件關閉,實際上是解除該磁盤文件與文件流的關聯,原來設置的工作方式也失效,這樣,就不能再通過文件流對該文件進行輸入或輸出
? ? 文件類型:1、ASCII文件:文件的每一個字節中均以ASCII代碼形式存放數據,即一個字節存放一個字符,這個文件就是ASCII文件(或稱字符文件)。
?????2、二進制文件:文件中的信息不是字符數據,而是字節中的二進制形式的信息,因此它又稱為字節文件
常用函數
打開文件:???
方式1:對文件輸出流、文件流對象,通過ofstream類的構造函數打開文件
????格式: ofstream (磁盤文件名, 輸入輸出方式); ?????
? ? 如果ofstream ?為0(假),表示打開操作失敗
????如: ??ofstream fout1(fname,ios::out);
????輸入輸出方式可以使用能夠進行組合使用的,以“或”運算(“|”)的方式,如:fstream fout(fname,ios::out|ios::in)
方式2:對文件的輸出和輸入流對象、文件流對象,都可通過open函數打開文件
????格式: 文件流對象.open(磁盤文件名, 輸入輸出方式); ?????
????返回值:為0(假),打開操作失敗
????如: ??fout.open(fname,ios::out)????? ?
關閉文件:
?在對已打開的磁盤文件的讀寫操作完成后,必須要關閉該文件??如: ?outfile.close( );
文件操作
? ? 1、可以用流插入運算符“<<”和流提取運算符“>>”輸入輸出標準類型的數據(>> 讀出時在遇空格、換行都結束)。
? ? 2、也可以用文件流的put、get、geiline等成員函數進行字符的輸入輸出。
#include <iostream>
using namespace std;
#include "fstream"int main()
{char fname[] = "d:/file1.txt";char buff[1024]= {0};/*********** 寫文件 *************///方式1 輸出流ofstream對象調用fopen函數ofstream fout;fout.open(fname,ios::out);if(!fout){cout<<"打開文件失敗"<<fname<<endl;}fout<< "hello world !"; //通過左移運算符寫入字符串fout.flush();fout.close();//方式2 調用輸出流ofstream對象的構造函數ofstream fout1(fname,ios::out);if(!fout1){cout<<"打開文件失敗"<<fname<<endl;}fout1.put('h'); //通過put函數寫入字符fout1.put('e');fout1.put('l');fout1.put('l');fout1.put('o');fout1.put('\n');fout1.flush();fout1.close();//文件流對象寫文件fstream file2(fname,ios::in|ios::out);file2<<"abdfd\n";file2<<"11111\n";file2.flush();file2.close();/*********** 讀文件 *************///輸入流ifstream對象讀取文件內容ifstream fin;fin.open(fname,ios::in);fin.getline(buff,1024); //通過getline函數讀取字符串cout<<buff<<endl; fin.close();//文件流對象讀文件內容fstream file1(fname,ios::in|ios::out);file1>>buff; //通過右移運算符讀出字符串file1.close();cout<<buff<<endl;system("pause");return 0;
}
二進制文件操作
????對二進制文件的讀寫主要用istream類的成員函數read和write來實現。這兩個成員函數的原型為
?????istream& read(char *buffer,int len);
?????ostream& write(const char * buffer,int len);
#include <iostream>
using namespace std;
#include <fstream>class Teacher
{
public:Teacher(){}Teacher(int age,char name[20]){this->age = age;strcpy(this->name,name);}void prinfInfo(){cout<<"Teacher name:"<<this->name<<" age:"<<this->age<<endl;}
private:int age;char name[20];
};int main()
{Teacher t1(31,"xiaoming");Teacher t2(32,"xiaohong");Teacher t3(33,"xiaohua");Teacher t4(34,"xiaoxin");char fname[] = "d:/file2";fstream fs(fname,ios::binary|ios::out);if(!fs){cout<<"文件打開失敗"<<endl;}fs.write((char *)&t1,sizeof(Teacher));fs.write((char *)&t2,sizeof(Teacher));fs.write((char *)&t3,sizeof(Teacher));fs.write((char *)&t4,sizeof(Teacher));fs.flush();fs.close();fstream fs2(fname,ios::binary|ios::in);if(!fs){cout<<"文件打開失敗"<<endl;}Teacher tt;fs2.read((char *)&tt,sizeof(Teacher));tt.prinfInfo();fs2.read((char *)&tt,sizeof(Teacher));tt.prinfInfo();fs2.read((char *)&tt,sizeof(Teacher));tt.prinfInfo();fs2.read((char *)&tt,sizeof(Teacher));tt.prinfInfo();fs2.close();system("pause");return 0;
}
輸出:
Teacher name:xiaoming age:31
Teacher name:xiaohong age:32
Teacher name:xiaohua age:33
Teacher name:xiaoxin age:34
?
?
?