C++中輸入輸出流及文件流操做筆記

一、流的控制

    iomanip          在使用格式化I/O時應包含此頭文件。
    stdiostream   用於混合使用C和C + +的I/O機制時,例如想將C程序轉變爲C++程序ios

二、類繼承關係


ios是抽象基類,由它派生出istream類和ostream類, iostream類支持輸入輸出操做,iostream類是從istream類和ostream類經過多重繼承而派生的類緩存

類ifstream繼承了類istream,類ofstream繼承了類ostream,類fstream繼承了 類iostream
iostream頭文件中4種流對象函數

對象this

含義spa

對應設備指針

對應的類code

c語言中相應的標準文件對象

cin繼承

標準輸入流ip

鍵盤

istream_withassign

stdin

cout

標準輸出流

屏幕

ostream_withassign

stdout

cerr

標準錯誤流

屏幕

ostream_withassign

stderr

clog

標準錯誤流

屏幕

ostream_withassign

stderr

cout補充
一、用「cout<<」輸出基本類型的數據時,能夠沒必要考慮數據是什麼類型,系統會判斷數據的類型

      並根據其類型選擇調用與之匹配的運算符重載函數。這個過程都是自動的,用戶沒必要干預。

        若是在C語言中用prinf函數輸出不一樣類型的數據,必須分別指定相應的輸出格式符,十分麻煩,並且容易出錯

二、cout流在內存中對應開闢了一個緩衝區,用來存放流中的數據,當向cout流插 人一個endl時,

     不論緩衝區是否已滿,都當即輸出流中全部數據,而後插入一個換行符, 並刷新流(清空緩衝區)。

        注意若是插人一個換行符」\n「(如cout<<a<<"\n"),則只輸出和換行,而不刷新cout 流(但並非全部編譯系統都體現出這一區別)。

三、在iostream中只對"<<"和">>"運算符用於標準類型數據的輸入輸出進行了重載,但未對用戶聲明的類型數據的輸入輸出 進行重載。

    若是用戶聲明瞭新的類型,並但願用"<<"和">>"運算符對其進行輸入輸出,按照重運算符重載來作。

cout 流一般是傳送到顯示器輸出,但也能夠被重定向 輸出到磁盤文件,而cerr流中的信息只能在顯示器輸出

cerr是不通過緩衝區,直接向顯示器上輸出有關信息,而clog中的信息存放在緩衝區中,緩衝區滿後或遇endl時向顯示器輸出

三、標準輸入流 cin

    重點掌握的函數
    cin.get()                 //讀入一個字符並返回它的值
    cin.get(一個參數)  //讀入一個字符並把它存儲在ch 
    cin.get(兩個參數)  //能夠讀取字符串
    cin.get(三個參數)  //能夠讀字符串        
    cin.getline()
    cin.ignore()           //讀取字符並忽略指定字符
    cin.peek()            //檢查下一個輸入的字符,不會把字符從流中移除
    cin.putback()       //返回一個字符給一個流

重要
一、使用cin,從流中讀出的字符,流中就沒有這字符了,再次讀取時只能讀取剩下的
二、緩衝去只有在遇到EOF、手動敲回車、流(緩存區)滿時,纔將流中的字符所有讀出(即清空緩存區)

練習
一、從流中取一個字符,而後在放進去;
二、判斷流中的第一個字符是否是放進去的那個字符;
三、從流中讀取10個字符;
四、從流中忽略5個字符,再讀取10個字符;
五、最後讀取剩下的字符,最後輸出讀到的全部字符

#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

四、標準輸出流 cout

  流成員函數

  cout.flush()      //清空緩衝區
  cout.put()        //把字符寫入流中
  cout.write()      //將字符串寫入當前輸出流中

  eg : cout.setf( ios::dec );

         cout.setf(ios::hex,ios::basefield);【建議使用這種】

  需注意:一、fmtflags setf( fmtflags flags ); 使用這種,必定要先取消當前基【cout.unself()】,以後才能夠設置新的基

 二、fmtflags setf( fmtflags flags, fmtflags needed ); 使用這種,第二個參數設爲當前的基,或者當不知道當前基時,設爲ios_base::basefield清除當前的全部可能的基    

  控制符,頭文件<iomanip>


 eg:  cout<<setw(5);

五、文件I/O

因爲文件設備並不像顯示器屏幕與鍵盤那樣是標準默認設備,不能像cout那樣預先定義的全局對象,因此咱們必須本身定義一個該類的對象。

ifstream類,它是從istream類派生的,用來支持從磁盤文件的輸入。

ofstream類,它是從ostream類派生的,用來支持向磁盤文件的輸出。

fstream類,它是從iostream類派生的,用來支持對磁盤文件的輸入輸出。

文件原理

    文件打開都有一個文件指針,該指針的初始位置由I/O方式指定,每次讀寫都從文件指針的當前位置開始。每讀入一個字節,指針就後移一個字節。當文件指針移到最後,就會遇到文件結束EOF(文件結束符也佔一個字節,其值爲-1),此時流對象的成員函數eof的值爲非0值(通常設爲1),表示文件結束 了

    文件關閉,其實是解除該磁盤文件與文件流的關聯,原來設置的工做方式也失效,這樣,就不能再經過文件流對該文件進行輸入或輸出

    文件類型:一、ASCII文件:文件的每個字節中均以ASCII代碼形式存放數據,即一個字節存放一個字符,這個文件就是ASCII文件(或稱字符文件)。

     二、二進制文件:文件中的信息不是字符數據,而是字節中的二進制形式的信息,所以它又稱爲字節文件

經常使用函數

打開文件:   

方式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( );

文件操做

    一、能夠用流插入運算符「<<」和流提取運算符「>>」輸入輸出標準類型的數據(>> 讀出時在遇空格、換行都結束)。

    二、也能夠用文件流的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
相關文章
相關標籤/搜索