14-1、IO流
- lO流打開和關閉
- lO流打開模式
- lO流對象的狀態
- 非格式化IO
- 二進制IO
- 讀取二進制數據
- 獲取讀長度
- 寫入二進制數據
- 讀寫指針 和 隨機訪問
- 設置讀/寫指針位置
- 獲取讀/寫指針位置
- 字符串流
lO流打開和關閉
通過構造函數打開I/O流
其中filename表示文件路徑,mode表示打開模式
- 打開輸入流
ifstream (const char* filename ,openmode mode) - 打開輸出流
ofstream(const char* filename , openmode mode); - 打開輸入輸出流
fstream (const char* filename , openmode mode);
lO流打開模式
- ios::out
打開文件用于寫入,不存在則創建,存在則清空
適用于ofstream(缺省)/fstream - ios::app
打開文件用于追加,不存在則創建,存在不清空
適用于ofstream/fstream - ios::trunc
打開時清空原內容
適用于ofstream/fstream - ios:in
打開文件用于讀取,不存在則失敗,存在不清空
適用于ifstream(缺省)/fstream - ios::ate
打開時定位文件尾
適用于ifstream/fstream - ios.:binary
以二進制模式讀寫
適用于ifstream/ofstream/fstream
#include <iostream>
#include <fstream>
using namespace std;
// C++標準庫已經設計好的類ofstream(文件輸出流)類int main( void ){ofstream ofs1("./file",ios::out);if(!ofs1){ // !(ofs1.operator bool())cout << "ofs1流對象狀態錯誤 -- 打開文件失敗" << endl;}ofs1 << 1234 << ' ' << 56.78 << ' ' << "Hello" << '\n';if(!ofs1){cout << "ofs1流對象狀態錯誤 -- 寫文件失敗" << endl;}ofs1.close();ofstream ofs2("./file",ios::app);if(!ofs2){ // !(ofs2.operator bool())cout << "ofs2流對象狀態錯誤 -- 打開文件失敗" << endl;}ofs2 << "World" << endl;;if(!ofs2){cout << "ofs2流對象狀態錯誤 -- 寫文件失敗" << endl;}ofs2.close();return 0;
}
#include <iostream>
#include <fstream>
using namespace std;
// C++標準庫已經設計好的類ifstream(文件輸入流)類int main( void ){ifstream ifs1("./file",ios::in);if(!ifs1){ // !(ifs1.operator bool())cout << "ifs1流對象狀態錯誤 -- 打開文件失敗" << endl;}int i; double d; string s1,s2;ifs1 >> i >> d >> s1 >> s2;if(!ifs1){cout << "ifs1流對象狀態錯誤 -- 讀文件失敗" << endl;}cout << i << ' ' << d << ' ' << s1 << ' ' << s2 << endl;ifs1.close();ifstream ifs2("./file",ios::ate);if(!ifs2){ // !(ifs2.operator bool())cout << "ifs2流對象狀態錯誤 -- 打開文件失敗" << endl;}ifs2.seekg(0,ios::beg);int ii; double dd; string ss1,ss2;ifs2 >> ii >> dd >> ss1 >> ss2;if(!ifs2){cout << "ifs2流對象狀態錯誤 -- 讀文件失敗" << endl;}cout << ii << ' ' << dd << ' ' << ss1 << ' ' << ss2 << endl;ifs2.close();return 0;
}
lO流對象的狀態
I/O流類對象內部保存當前狀態,其值為以下常量的位或
- ios:goodbit: 0,一切正常
- ios::badbit: 1,發生致命錯誤
- ios::eofbit: 2,遇到文件尾
- ios::failbit: 4,打開文件失敗或實際讀寫字節數未達預期
l/O流類對象支持到bool類型的隱式轉換
- 發生1,2,4等情況,返回false,否則返回true
- 將I/O流對象直接應用到布爾上下文中,即可實現轉換
處于1或4狀態的流,在復位前無法工作
#include <iostream>
#include <fstream>
using namespace std;
// C++標準庫已經設計好的類ifstream(文件輸入流)類int main( void ){ifstream ifs2("./file",ios::ate);if(!ifs2){ // !(ifs2.operator bool())cout << "ifs2流對象狀態錯誤 -- 打開文件失敗" << endl;}int ii; double dd; string ss1,ss2;cout << "--------------------第一次讀數據-----------------------" << endl;ifs2 >> ii >> dd >> ss1 >> ss2;// ifs2.operator>>(ii).operator>>(dd)>>operator>>(ss1)>>operator>>(ss2)if(!ifs2){cout << "ifs2流對象狀態錯誤 -- 讀文件失敗" << endl;cout << "ifs2是0狀態嗎?" << ifs2.good() << ", ifs2是1狀態嗎?" << ifs2.bad()<< ", ifs2是2狀態嗎?" << ifs2.eof() << ", ifs2是4狀態嗎?" << ifs2.fail() << endl;cout << "ifs2的具體狀態:" << ifs2.rdstate() << endl;}cout << ii << ' ' << dd << ' ' << ss1 << ' ' << ss2 << endl;ifs2.clear();ifs2.seekg(0,ios::beg);cout << "--------------------第二次讀數據-----------------------" << endl;ifs2 >> ii >> dd >> ss1 >> ss2;// ifs2.operator>>(ii).operator>>(dd)>>operator>>(ss1)>>operator>>(ss2)if(!ifs2){cout << "ifs2流對象狀態錯誤 -- 讀文件失敗" << endl;cout << "ifs2是0狀態嗎?" << ifs2.good() << ", ifs2是1狀態嗎?" << ifs2.bad()<< ", ifs2是2狀態嗎?" << ifs2.eof() << ", ifs2是4狀態嗎?" << ifs2.fail() << endl;cout << "ifs2的具體狀態:" << ifs2.rdstate() << endl;}cout << ii << ' ' << dd << ' ' << ss1 << ' ' << ss2 << endl;ifs2.close();return 0;
}
非格式化IO
- 寫入字符
ostream& ostream::put (char ch);一次向輸出流寫入一個字符,返回流本身 - 刷輸出流
ostream& ostream::flush (void);將輸出流緩沖區中的數據刷到設備上,返回流本身 - 讀取字符
int istream::get (void);成功返回讀到的字符,失敗或遇到文件尾返回EOF
istream& istream::get (char& ch);返回輸入流本身,其在布爾上下文中的值,成功為true,失敗或遇到文件尾為false - 讀取行
istream& istream::getline (char* buffer,streamsize num, char delim = ‘\ n’);- 讀取字符 (至定界符)到buffer中。
- 一旦讀取了num個字符還未讀取定界符,第num個字符設置為 ‘\0’,返回 (輸入流對象狀態為4)。
- 如果因為遇到定界符 (缺省為 ‘\n’ ) 返回 (輸入流對象狀態為0)定界符被讀取并丟棄,追加結尾空字符 ‘\0’,讀指針停在該定界符的下一個位置
- 遇到文件尾,返回 (輸入流對象狀態為6)
#include <iostream>
#include <fstream>
using namespace std;// C++標準庫已經設計好的類ofstream(文件輸出流)、ifstream(文件輸入流)類int main( void ){ofstream ofs("./noformat",ios::out);if(!ofs)cout << "ofs流對象狀態錯誤 -- 打開文件失敗" << endl;for( char c = ' '; c <= '~';c++)ofs.put(c).flush();ofs.close();ifstream ifs("./noformat",ios::in);if(!ifs)cout << "ifs流對象狀態錯誤 -- 打開文件失敗" << endl;char c;// 單參getwhile(1){ifs.get(c);if(!ifs)break;elsecout << c;}cout << endl;ifs.clear();ifs.seekg(0,ios::beg);// 無參getwhile(1){c = ifs.get();if( c == EOF )break;elsecout << c;}cout << endl;ifs.close();return 0;
}
#include <iostream>
#include <fstream>
using namespace std;// C++標準庫已經設計好的類ofstream(文件輸出流)、ifstream(文件輸入流)類int main( void ){ifstream ifs("./getline",ios::in);if(!ifs)cout << "ifs流對象狀態錯誤 -- 打開文件失敗" << endl;char buf[256];while(1){ifs.getline(buf,256,'\n');if(!ifs)break;else{cout << buf << endl;cout << "ifs流對象狀態值:" << ifs.rdstate() << endl;}}
/*ifs.getline(buf,256,'\n'); // aa\ncout << buf << endl;cout << "ifs流對象狀態值:" << ifs.rdstate() << endl;ifs.getline(buf,256,'\n'); // bbbb\ncout << buf << endl;cout << "ifs流對象狀態值:" << ifs.rdstate() << endl;ifs.getline(buf,256,'\n'); // cccccc\ncout << buf << endl;cout << "ifs流對象狀態值:" << ifs.rdstate() << endl;ifs.getline(buf,256,'\n'); // dddddddd\ncout << buf << endl;cout << "ifs流對象狀態值:" << ifs.rdstate() << endl;ifs.getline(buf,256,'\n'); // 0123456789\ncout << buf << endl;cout << "ifs流對象狀態值:" << ifs.rdstate() << endl;ifs.getline(buf,256,'\n'); // cout << buf << endl;cout << "ifs流對象狀態值:" << ifs.rdstate() << endl;
*/ ifs.close();return 0;
}
二進制IO
讀取二進制數據
istream& istream::read (char* buffer,streamsize num)
- 從輸入流中讀取num個字節到緩沖區buffer中
- 返回流對象本身,其在布爾上下文中的值,成功(讀滿)為true,失敗(沒讀滿)為false
- 如果沒讀滿num個字節,函數就返回了,比如遇到文件尾,最后一次讀到緩沖區,buffer中的字節數可以通過istream::gcount()函數獲得
#include <iostream>
#include <fstream>
using namespace std;// C++標準庫已經設計好的類ofstream(文件輸出流)、ifstream(文件輸入流)類int main( void ){ofstream ofs("./binary",ios::out);if(!ofs)cout << "ofs流對象狀態錯誤 -- 打開文件失敗" << endl;ifstream ifs("./getline",ios::in);if(!ifs)cout << "ifs流對象狀態錯誤 -- 打開文件失敗" << endl;char buf[3];while(1){ifs.read(buf,3);if(ifs){ofs.write(buf,3);
// cout << buf; // 讀滿3個字符}else{// 沒有讀滿3個字符int len = ifs.gcount();ofs.write(buf,len);
// buf[len]='\0';
// cout << buf;break;}}ifs.close();ofs.close();return 0;
}
獲取讀長度
streamsize istream::gcount (void)
返回最后一次從輸入流中讀取的字節數
寫入二進制數據
ostream& ostream::write (const char* buffer,streamsize num);
- 將緩沖區buffer中的num個字節寫入到輸出流中
- 返回流本身,其在布爾上下文中的值,成功(寫滿)為true,失敗(沒寫滿)為false
#include <iostream>
#include <fstream>
using namespace std;// C++標準庫已經設計好的類ofstream(文件輸出流)、ifstream(文件輸入流)類int main( void ){ofstream ofs("./binary",ios::out);if(!ofs)cout << "ofs流對象狀態錯誤 -- 打開文件失敗" << endl;ifstream ifs("./getline",ios::ate);if(!ifs)cout << "ifs流對象狀態錯誤 -- 打開文件失敗" << endl;int size = ifs.tellg();char buf[size];ifs.seekg(0,ios::beg);ifs.read(buf,size);ofs.write(buf,size);ifs.close();ofs.close();return 0;
}
讀寫指針 和 隨機訪問
設置讀/寫指針位置
istream& istream::seekg (off_type offset,ios::seekdir origin);
ostream& ostream::seekg (off_type offset,ios::seekdir origin);
origin表示偏移量offset的起點:
ios::beg
從文件的第一個字節ios::cur
從文件的當前位置ios::end
從文件最后一個字節的下一個位置
offset為負/正表示向文件頭/尾的方向偏移
讀/寫指針被移到文件頭之前或文件尾之后,則失敗
獲取讀/寫指針位置
返回讀/寫指針當前位置相對于文件頭的字節偏移量
pos type istream::tellg (void);
pos type ostream::tellp (void):
字符串流
輸出字符串流
#include <sstream>
ostringstream oss ;
oss << 1234 << ' ' << 56.78 <<' '<< "ABCD";
string os = oss.str();
輸入字符串流
#include <sstream>
string is ("1234 56.78 ABCD") ;
istringstream iss (is);
int i;
double d;
string s;
iss >> i >> d >> s;