首頁 > 軟體

C++超詳細梳理IO流操作

2022-07-02 14:00:31

C++定義了I/O標準類庫,這些每個類都稱為流/流類,用以完成某方面的功能

C++ 系統實現了一個龐大的類庫,其中 ios 為基礎類別,其他類都是直接或間接派生自 ios 類

1.標準輸出輸入流-控制檯流(iostream類) 

cin實際上是一個標準輸入流物件(類物件),常用的方式有,cin>>(cin.operator>>()), cin.get(), cin.getline()(用法:cin.getline(char s[], int nLength))

或者在std名稱空間下,有一個單獨的getline()函數,但是該函數時使用string物件作為引數的,即:getline(cin, str)

cout是標準輸出流物件(類物件),cout<<

cout cin printf scanf(格式化輸入輸出)比較

總結:c++中儘量用cin和cout

//c_str()就是把string類物件轉換成和c相容的char*型別。
//這是為了與c語言相容,在c語言中沒有string型別
//故必須通過string類物件的成員函數c_str()把string 物件轉換成c中的字串樣式
//例如
	string a = "hellofjifj";
	printf("%sn", a.c_str());
	//printf("%sn", a);//這樣會有問題

2. 檔案流(I/O操作)

在檔案流中提供了三個派生類對檔案資料進行操作(注意這裡是類,不像控制檯提供的是類物件)

  • ofstream:輸出,即寫檔案,由ostream引申而來
  • ifstream:輸入,即讀取檔案,由istream引申而來
  • fstream :輸入輸出,同時讀寫操作,由iostream引申而來

檔案的型別:文字檔案 和 二進位制檔案

檔案讀寫的步驟:

  • 包含的標頭檔案:#include <fstream>
  • 建立流
  • 開啟檔案(檔案和流關聯)
  • 讀寫 (寫操作:<<,put( ),write( )讀操作:>> , get( ),getline( ), read( ))
  • 關閉檔案:把緩衝區資料完整地寫入檔案, 新增檔案結束標誌, 切斷流物件和外部檔案的連線

文字檔案

使用<< >> 進行讀寫

<< 能實現以行為單位寫入檔案

>> 不能一行為單位讀入記憶體,而是以單詞為單位。總是以空格、Tab、回車結束

    ofstream OpenFile("file.txt");  
  if (OpenFile.fail())  
  {  
    cout<<"開啟檔案錯誤!"<<endl;  
    exit(0);  
  }  
    OpenFile << "abc def ghi";//把內容寫入file檔案  
  OpenFile.close();    
    const int len=20;  
    char str[len];  
    ifstream OpenFile("file.txt");  
  if (OpenFile.fail())  
    {  
        cout<<"開啟檔案錯誤!"<<endl;  
        exit(0);  
    }  
    OpenFile >> str;  
    cout << str << endl;  
    OpenFile.close(); //str的內容為abc,而不是abc def ghi(見空格停止)

getline()讀取一行

getline():以行為單位讀入記憶體,能一次讀入一行

函數原型:istream &getline( char *buffer, streamsize num );

getline( )函數用於從檔案讀取num個字元到buffer(記憶體)中,直到下列情況發生時,讀取結束:

  • num個字元已經讀入
  • 碰到一個換行標誌
  • 碰到一個EOF
    const int len=20;  
    char str[len];  
    ifstream OpenFile("file.txt");  
    if (OpenFile.fail())  
    {  
        cout<<"開啟檔案錯誤!"<<endl;  
        exit(0);  
    }  
    OpenFile.getline(str,20);  
    cout << str << endl;  
    OpenFile.close();//執行結果:str的內容為abc def ghi (一直把一行讀完)

get() put()進行單個字元讀寫

ostream& put (char c);

函數功能:使用 put( )函數,向檔案中寫入字元

    char ch='1';  
    ofstream OpenFile("file.txt");  
  if (OpenFile.fail())  
    {  
        cout<<"開啟檔案錯誤!"<<endl;  
        exit(0);  
    }  
    OpenFile.put(ch); // 把字元1寫入檔案
    OpenFile.close();  

istream& get (char& c);

函數功能:使用 get( )函數,從檔案中讀取字元

    char ch;  
    ifstream OpenFile("file.txt");  
  if (OpenFile.fail())  
    {  
        cout<<"開啟檔案錯誤!"<<endl;  
        exit(0);  
    }  
    OpenFile.get(ch);  
    cout << ch; //把字元1從檔案中讀到ch(記憶體)中
    OpenFile.close();  

二進位制檔案讀寫

get() put()進行單個位元組讀寫

ofstream &put(char ch)

在記憶體中寫入一個位元組到檔案

    char ch='a';  
    ofstream OpenFile("file.txt",ios::binary);  
    //以二進位制的方式處理,在開啟時要用 ios::binary 顯式宣告
  if (OpenFile.fail())  
    {  
        cout<<"開啟檔案錯誤!"<<endl;  
        exit(0);  
    }  
    OpenFile.put(ch);  
    OpenFile.close();  

ifstream &get(char ch)

在檔案中讀取一個位元組到記憶體

    char ch;  
    ifstream OpenFile("file.txt",ios::binary);  
  if (OpenFile.fail())  
    {  
        cout<<"開啟檔案錯誤!"<<endl;  
        exit(0);  
    }  
    OpenFile.get(ch); // 從檔案中讀取一個字元
    cout << ch;  
    OpenFile.close(); 

read() write()多個位元組讀寫

ostream & ostream :: write ( char * buf , int n ) ;

功能:把buf指向的內容取n個位元組寫入檔案

引數說明:buf表示要寫入記憶體的地址,傳參時要取地址。n表示要讀入位元組的長度

注意:

  • 該函數遇到空字元時並不停止,因而能夠寫入完整的類結構
  • 第一個引數一個char型指標(指向記憶體資料的起始地址),與物件結合使用的時候,要在物件地址之前要char做強制型別轉換
    char ch[12]="12 3 456 78";  
    ofstream OpenFile("file.txt");  
  if (OpenFile.fail())  
    {  
        cout<<"開啟檔案錯誤!"<<endl;  
        exit(0);  
    }  
    OpenFile.write(ch, 12);  
    OpenFile.close();  

istream & read ( char * buf , int n ) ;

功能:從檔案中提取 n 個位元組資料,寫入buf指向的地方中

    char ch[12];  
    ifstream OpenFile("file.txt");  
    if (OpenFile.fail())  
    {  
        cout<<"開啟檔案錯誤!"<<endl;  
        exit(0);  
    }  
    OpenFile.read(ch,12);  
    cout << ch;  //執行結果:陣列ch的內容為12 3 456 78
    OpenFile.close();  

注意事項

(1)程式不再使用檔案時,為什麼要關閉檔案?

因為:

  • 檔案緩衝區是一塊小的記憶體空間.
  • 作業系統限制同時開啟的檔案數量

注意:close ( ) 函數關閉檔案,但流物件仍然存在。

(2)檔案的預設開啟方式為文字檔案,要是想以二進位制的方式處理,在開啟時要用 ios::binary 顯式宣告。

(3)針對文字檔案操作時,get函數和>>的區別:

  • 在讀取資料時,get函數包括空白字元(遇空白字元不停止讀取)
  • >>在預設情況下拒絕接受空白字元(遇到空白符停止讀取)

(4)文字檔案的讀寫常使用的方法:使用<<寫入檔案,使用getline 和 >> 讀到記憶體

二進位制檔案的讀寫常使用的方法:使用istream 類的成員函數read 和write 來實現,

3.字串輸入輸出流(sstream)

其相應的派生類有istringstream類、ostringstream類、iostringstream類

sprintf sscanf 和 stringstream的使用

其實是整型和字元創型別的相互轉化:序列化(轉成字串)和反序列化(將字串中資料提取處理)

C當中用法:sprintf和sscanf函數

C++中用法:字串流

struct ServerInfo//要讀些的資訊類
{
	char _ip[20];
	int  _port;
};
	//C當中用法
    //將info中資料轉成字串並存入buff中
	ServerInfo info = { "192.0.0.1", 8000 };
	char buff[128];//buff的大小不好確定
	sprintf_s(buff, "%s %d", info._ip, info._port);// 序列化,轉成字串存入buff中
	
    //將buff中資料格式化輸出到rinfo中
	ServerInfo rinfo;
	sscanf(buff, "%s%d", rinfo._ip, &rinfo._port);// 反序列化,將字串buff中資料轉成規定格式
	//空格間隔開了
	//C++用法
	//將info中資料轉成字串並存到buff中
    ServerInfo info = { "192.0.0.1", 8000 };
	stringstream ssm;//字串流物件
	ssm << info._ip <<" "<<info._port;//轉成字串
	string buff = ssm.str();//檢視字串
	//從字串提取至rinfo
	stringstream ssm;
	ssm.str("127.0.0.1 90");//這兩行直接按照下面的寫法也行
	//stringstream ssm("127.0.0.1 90");
	ServerInfo rinfo;
	ssm >> rinfo._ip >> rinfo._port;

補充內容:C/C++中int和字串型別的轉換

string轉int

  • atoi(c庫函數、ascll to integer)
  • strtol(c庫函數,字串轉成長整型)
  • stoi(stoi是C++的函數,標頭檔案:#include < string >)

int轉string

  • itoa(c庫函數)
  • to_string(C++11的函數,可以適應8種型別的過載,將其轉換為string,標頭檔案:#include < string >)

多功能轉換

stringstream

到此這篇關於C++超詳細梳理IO流操作的文章就介紹到這了,更多相關C++ IO流內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com