C++標准輸入流、輸出流以及文件流


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};

<span class="hljs-comment">//從流中取一個字符,然后在放進去</span>
ch1 = <span class="hljs-built_in">cin</span>.get();
<span class="hljs-built_in">cin</span>.putback(ch1);

<span class="hljs-comment">//判斷流中的第一個字符是不是放進去的那個字符</span>
look = <span class="hljs-built_in">cin</span>.peek();
<span class="hljs-keyword">if</span>(look == (<span class="hljs-keyword">int</span>)ch1)
{
	<span class="hljs-built_in">cout</span>&lt;&lt;<span class="hljs-string">"cin.peek()放進去的字符在第一個位置"</span>&lt;&lt;<span class="hljs-built_in">endl</span>;
}
<span class="hljs-keyword">else</span>
{
	<span class="hljs-built_in">cout</span>&lt;&lt;<span class="hljs-string">"cin.peek()放進去的字符不是在第一個位置"</span>&lt;&lt;<span class="hljs-built_in">endl</span>;
}

<span class="hljs-comment">//從流中讀取10個字符</span>
<span class="hljs-built_in">cin</span>.get(str1,<span class="hljs-number">11</span>);

<span class="hljs-comment">//從流中忽略5個字符,再讀取10個字符</span>
<span class="hljs-built_in">cin</span>.ignore(<span class="hljs-number">5</span>);
<span class="hljs-built_in">cin</span>.get(str2,<span class="hljs-number">11</span>,EOF);

<span class="hljs-comment">//最后讀取剩下的字符,最后輸出讀到的所有字符</span>
<span class="hljs-built_in">cin</span>.getline(str3,<span class="hljs-number">100</span>);

<span class="hljs-comment">//輸出讀到的數據</span>
<span class="hljs-built_in">cout</span>&lt;&lt;<span class="hljs-string">"第一個字符"</span>&lt;&lt;ch1&lt;&lt;<span class="hljs-built_in">endl</span>;
<span class="hljs-built_in">cout</span>&lt;&lt;<span class="hljs-string">"第一組 字符串:"</span>&lt;&lt;str1&lt;&lt;<span class="hljs-built_in">endl</span>;
<span class="hljs-built_in">cout</span>&lt;&lt;<span class="hljs-string">"第二組 字符串:"</span>&lt;&lt;str2&lt;&lt;<span class="hljs-built_in">endl</span>;
<span class="hljs-built_in">cout</span>&lt;&lt;<span class="hljs-string">"剩下的字符串:"</span>&lt;&lt;str3&lt;&lt;<span class="hljs-built_in">endl</span>;

system(<span class="hljs-string">"pause"</span>);
<span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;

}

輸出:

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

<span class="hljs-comment">//方式2 調用輸出流ofstream對象的構造函數</span>
<span class="hljs-function">ofstream <span class="hljs-title">fout1</span><span class="hljs-params">(fname,ios::out)</span></span>;
<span class="hljs-keyword">if</span>(!fout1)
{
	<span class="hljs-built_in">cout</span>&lt;&lt;<span class="hljs-string">"打開文件失敗"</span>&lt;&lt;fname&lt;&lt;<span class="hljs-built_in">endl</span>;
}
fout1.put(<span class="hljs-string">'h'</span>); <span class="hljs-comment">//通過put函數寫入字符</span>
fout1.put(<span class="hljs-string">'e'</span>);
fout1.put(<span class="hljs-string">'l'</span>);
fout1.put(<span class="hljs-string">'l'</span>);
fout1.put(<span class="hljs-string">'o'</span>);
fout1.put(<span class="hljs-string">'\n'</span>);
fout1.flush();
fout1.close();

<span class="hljs-comment">//文件流對象寫文件</span>
<span class="hljs-function">fstream <span class="hljs-title">file2</span><span class="hljs-params">(fname,ios::in|ios::out)</span></span>;
file2&lt;&lt;<span class="hljs-string">"abdfd\n"</span>;
file2&lt;&lt;<span class="hljs-string">"11111\n"</span>;
file2.flush();
file2.close();

<span class="hljs-comment">/***********  讀文件  *************/</span>
<span class="hljs-comment">//輸入流ifstream對象讀取文件內容</span>
ifstream fin;
fin.open(fname,ios::in);
fin.getline(buff,<span class="hljs-number">1024</span>);		<span class="hljs-comment">//通過getline函數讀取字符串</span>
<span class="hljs-built_in">cout</span>&lt;&lt;buff&lt;&lt;<span class="hljs-built_in">endl</span>;	
fin.close();

<span class="hljs-comment">//文件流對象讀文件內容</span>
<span class="hljs-function">fstream <span class="hljs-title">file1</span><span class="hljs-params">(fname,ios::in|ios::out)</span></span>;
file1&gt;&gt;buff;	<span class="hljs-comment">//通過右移運算符讀出字符串</span>
file1.close();
<span class="hljs-built_in">cout</span>&lt;&lt;buff&lt;&lt;<span class="hljs-built_in">endl</span>;


system(<span class="hljs-string">"pause"</span>);
<span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;

}


二進制文件操作

    對二進制文件的讀寫主要用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(<span class="hljs-keyword">int</span> age,<span class="hljs-keyword">char</span> name[<span class="hljs-number">20</span>])
{
	<span class="hljs-keyword">this</span>-&gt;age = age;
	<span class="hljs-built_in">strcpy</span>(<span class="hljs-keyword">this</span>-&gt;name,name);
}
<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">prinfInfo</span><span class="hljs-params">()</span>
</span>{
	<span class="hljs-built_in">cout</span>&lt;&lt;<span class="hljs-string">"Teacher name:"</span>&lt;&lt;<span class="hljs-keyword">this</span>-&gt;name&lt;&lt;<span class="hljs-string">"   age:"</span>&lt;&lt;<span class="hljs-keyword">this</span>-&gt;age&lt;&lt;<span class="hljs-built_in">endl</span>;
}

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

<span class="hljs-function">fstream <span class="hljs-title">fs2</span><span class="hljs-params">(fname,ios::binary|ios::in)</span></span>;
<span class="hljs-keyword">if</span>(!fs)
{
	<span class="hljs-built_in">cout</span>&lt;&lt;<span class="hljs-string">"文件打開失敗"</span>&lt;&lt;<span class="hljs-built_in">endl</span>;
}
Teacher tt;
fs2.read((<span class="hljs-keyword">char</span> *)&amp;tt,<span class="hljs-keyword">sizeof</span>(Teacher));
tt.prinfInfo();
fs2.read((<span class="hljs-keyword">char</span> *)&amp;tt,<span class="hljs-keyword">sizeof</span>(Teacher));
tt.prinfInfo();
fs2.read((<span class="hljs-keyword">char</span> *)&amp;tt,<span class="hljs-keyword">sizeof</span>(Teacher));
tt.prinfInfo();
fs2.read((<span class="hljs-keyword">char</span> *)&amp;tt,<span class="hljs-keyword">sizeof</span>(Teacher));
tt.prinfInfo();
fs2.close();

system(<span class="hljs-string">"pause"</span>);
<span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;

}

輸出:

Teacher name:xiaoming   age:31
Teacher name:xiaohong   age:32
Teacher name:xiaohua   age:33
Teacher name:xiaoxin   age:34

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM