一、io庫的基本工具
• istream(輸入流)類型,提供輸入操作。
• ostream(輸出流)類型,提供輸出操作。
• cin:讀入標準輸入的 istream 對象。
• cout:寫到標準輸出的 ostream 對象。
• cerr:輸出標準錯誤的 ostream 對象。cerr 常用於 程序錯誤信息。
• >> 操作符,用於從 istream 對象中讀入輸入。
• << 操作符,用於把輸出寫到 ostream 對象中。
• getline 函數,需要分別取 istream 類型和 string 類型的兩個引用形 參,其功能是從 istream 對象讀取一個單詞(空格分隔),然後寫入 string 對象中。
二、io庫的條件狀態控制
參照C++Primer中的函數表
上述反應了輸入輸出流的條件狀態
//例子1
if(cin)
//符合語法,表示可以用cin
while(cin>>n)
//合法用法,檢查了流的狀態,如果輸入成功條件爲true
//當出現系統級故障,讀入無效數據或者遇到結束符eof時都會返回false
上面的例子1只能驗證輸入是否有效,而某些程序則需要更詳細地訪問或控制流的狀態,此時,除了知道流處於錯誤狀態外,還必須瞭解它遇到了哪種類型的錯誤。 這就用到了表中的類型和函數。
流的狀態由 bad、fail、eof 和 good 操作提示。如果 bad、fail 或者 eof 中的任意一個爲 true,則該流處於錯誤狀態。如果這三個條件沒有一個爲 true,則 good 操作將返回 true。
#include<iostream>
#include<stdexcept>
using namespace std;
int main()
{
int i;
while (cin >> i, !cin.eof())//逗號操作符:首先計算它的每一個操作數,然後返回右邊操作數作爲整個操作的結果,cin.eof():如果到達終止符,返回true,這裏表示沒有到達終止符
{
if (cin.bad())
throw runtime_error("IO stream Corrupted"); //系統出現故障,輸入流崩潰
if (cin.fail()) //輸入類型不符合,可修正,所以continue
{
cerr << "bad data, try again" << endl;
cin.clear();//重置cin但是不清除內容
cin.sync();//清楚錯誤內容
//cin.clear(istream::failbit); //此處爲C++primer的寫法,程序會陷入死循環,原因是cin.clear(istream::failbit);就是使failbit位設置爲1,而把eofbit和badbit位清除爲0。
continue;
}
cout << i << endl; //輸入成功,可以正確使用i
}
}
下面是函數返回和調用istream的例子
#include<iostream>
#include<stdexcept>
using namespace std;
istream& fun(istream &i)
{
int k;
while (i>>k,!i.eof())
{
if (i.bad())
{
throw runtime_error("Corrupted");
}
if (i.fail())
{
cerr << "unexpected data,try again" << endl;
i.clear();
i.sync();
continue;
}
cout << k << endl;
}
i.clear();
return i;
}
int main()
{
int k;
fun(cin);
system("pause");
}
輸出緩衝區的刷新例子
cout << "zlk_flush" << flush; //直接刷新
cout << "zlk_ends" << ends; //空一格再刷新
cout << "zlk_endl" << endl; //空一行再刷新
三、iostream,fstream,sstream
1、iostream 爲讀寫控制窗口
2、fstream爲讀寫以命名文件
3、sstream爲讀寫存儲在內存的string對象
其類之間的派生關係爲:
1、iostream:
istream類和ostream類以及iostream類不可自行創建對象,只能用iostream頭文件裏的全局變量cin 和cout 進行流輸入和流輸出。
2、fstream
文件流的使用例子:
#include<iostream>
#include<fstream>
#include<string>
#include<vector>
using namespace std;
int main()
{
string s;
string file_in_str;
string file_out_str;
file_in_str = "E:\\testin.txt";
string next_file = "E:\\testin2.txt";
file_out_str = "E:\\testout.txt";
//ifstream filein(file_in_str.c_str); //另外一種打開方式
//ofstream fileout(file_out_str.c_str);
ifstream filein;
ofstream fileout;
filein.open(file_in_str); //調用open方法綁定文件,當要給filein綁定新文件前要調用close()函數
fileout.open(file_out_str);
//filein.close();
if (!filein) //當open操作失敗,filein爲0
{
cerr << "錯誤:打開文件失敗:" << file_in_str << endl;
}
vector<string> kk;
while (getline(filein, s)) //讀輸入流的一個行
//while (filein>>s) //讀輸入流的一個單詞(遇到空格停止)
{
kk.push_back(s);
}
for (vector<string>::iterator i = kk.begin(); i < kk.end(); i++)
{
cout << *i << endl;
}
filein.close();//關閉文件
filein.clear();//刷新緩衝區
}
上例中filein.open()的文件打開還支持文件打開方式,放到第二個參數就好,下面是打開方式列表:
還有可用的組合方式:
3、sstream
sstream的基本思路可以吧fstream中綁定的文件換成字符串,然後從字符串中讀取。
stringstream的基本使用:
#include<iostream>
#include<sstream>
#include<string>
using namespace std;
int main()
{
string s1, s2;
while (getline(cin, s1))
{
stringstream stri(s1); //給stingstream綁定一個string對象
cout << stri.str() << endl; //stri.str()爲string流所有內容(一直到結束符)
while (stri >> s2) //從string流s1中讀單詞,讀到流末尾結束
{
cout << s2 << endl;
}
}
}
該類型流主要是爲了類型轉化,例如,有一個數值型數據集合,要獲取它們的 string 表 示形式,或反之。詳情請看下面例子:
#include<iostream>
#include<sstream>
#include<string>
using namespace std;
int main()
{
int a = 10, b = 24;
string s="99";
ostringstream oss;
oss.str(s); //綁定字符串s
oss << a << b; //輸入到字符串的時候不會從99的結尾接着輸出,而是直接修改原來的數據
string res = oss.str(); //將int型的a和b輸入到字符串res中了
cout << res << endl;//輸出爲1024
}
用istringstream從string中讀取int(float也可以)
#include<iostream>
#include<sstream>
#include<string>
using namespace std;
int main()
{
string a = "1001 23";
istringstream iss;
iss.str(a); //綁定字符串a
cout << istr.str() << endl;
int x, y, z;
iss >> x >> y;
z = x + y;
cout << z << endl;
}
ENDL;