1、資料 記憶體中 變數
磁碟上 檔案
2、把資料從其他的裝置搬到記憶體中 --- 輸入 --- 讀
把記憶體中的資料放到其他裝置中 --- 輸出 --- 寫
3、流
物質的定向移動,輸入輸出資料流中是資料的定向移動
輸入資料流的源頭 : 檔案 目的地:記憶體
輸出資料流的源頭 : 記憶體 目的地:檔案
4、標準輸出裝置 --- 顯示器
標準輸入裝置 --- 鍵盤
鍵盤 --- 記憶體 --- 顯示器
| |
輸入操作 輸出操作
輸入輸出資料流 : 記憶體與磁碟之間,記憶體與標準輸入輸出裝置之間的
5、cout 源 :變數 目的地 :顯示器
cin 鍵盤 記憶體中某一變數
6、標準輸入資料流 cin istream的一個對象
標準輸出資料流 cout ostream的一個對象
標準錯誤流 cerr 目的地都是螢幕,用cout替代
7、cin
是一個帶有緩衝的標準的輸入對象,預設輸入裝置是鍵盤
(1) >> : 自動校正資料類型
遇到斷行符號才會開始讀資料,遇到空格就結束,只能讀一個單詞
流是資料的定向移動,被讀走的資料就消失,沒有讀走的資料會一直留在流中,直到流的消失,資料也跟著消失
流中有資料,就會阻塞,等待讀取 --- 所有輸入方法的特性
為什麼 ">>"可以連續使用? 因為返回就是istream對象本身的引用
注意 : ">>" 不讀斷行符號,不讀空格
(2)get(): 每次 讀一個字元。返回一個整數,實際上是讀到字元的ASCII碼
把斷行符號,空格都當作一般字元讀出來
(3)get(char&):把讀到的內容存到參數中
cin.get(arr[0]).get(arr[1]); //get(char&)返回cin本身,可以連續使用
(4)getline(str,256) : 讀取一行,包括空格
對於斷行符號,唯讀走,不儲存
會讀取數組長度減1個字元,最後一個放'\0'
輸入資料超過給定的空間 (1)截斷資料,剩下的資料還在流裡
(2)設定一個錯誤標記,調用cin.clear(),清除錯誤,繼續工作
View Code
#include <iostream> using namespace std; int main(){ int age; char name[20] ; cout << "enter your age >"; cin >> age; cin.get(); //讀取流中殘餘的斷行符號,以便getline能正常工作 // cin.ignore(20,'\n'); //忽略20個字元或者碰到斷行符號,從流中清除 cout << "enter your name >"; cin.getline(name,20); cout << "your age is :" << age << endl; cout << "your name is :" << name << endl; }
(5)read(char*,int) char*是存結果的地址,int是讀的長度,並且不能比前面的數組的空間大
讀滿為止 ,特殊字元也當做一般字元處理
超出的部分仍然存在流裡面
只要資料沒讀滿,一直阻塞
不會自動補'\0' --- 傳參數的時候,數組長度傳減1的長度,補齊'\0'以免亂碼
所有輸入資料流的共同特徵:只要沒資料就阻塞
讀不完的就留在流裡
(6)cin.ignore(255,'\n') 忽略255個字元或者遇到'\n',如果在前255個字元中出現'\n',則就忽略到'\n'之前的字元
(7)peek() 查看流裡的第一個字元是什麼
只察看,不讀走
(8)putback() 向流中插入字元,前提必須有空位的時候
必須與get()一起使用,用get()取出一個字元,才能用putback()插入一個字元
(9)cin.fail()判斷是否出現錯誤標誌,一切正常返回false
當用cin讀取的資料類型出現錯誤的時候,這是一種不可恢複的錯誤,用cin.clear()是不能清除錯誤標記的
在鍵盤上讀取,用getline()可以確保輸入資料流的正常形成,讀取後採取強制轉換類型得到自己需要的資料
8、ifstream
(1)需要#include <fstream>標頭檔
ifstream ifs("test.txt"); //建立一個ifstream的對象,開啟檔案,給建構函式傳如一個參數,就是文要開啟的檔案名稱
//檔案的在目前的目錄下找,也可以用相對路徑或絕對路徑找檔案
在開啟檔案之後,立即判斷開啟檔案是否成功
if( ifs.fail() ){ cout << "Can't open test " <<endl; return 0; } if( ! ifs ){ //也可以這樣判斷檔案開啟是否出錯 cout << "Can't open test " <<endl; return 0; }
(2)在檔案結束的時候都會有"EOF"標誌,作為檔案結束的標誌符
可以用判斷是否讀到"EOF",來判斷時候讀到檔案尾了
if(ifs.eof()){ break; }
(3)對於一個進程可開啟檔案的數量是有數的,所以檔案屬於資源
所以在使用完畢以後,要關閉檔案輸入資料流
練習:(1)把/etc/passwd 檔案列印出來
(2)把檔案中不以"#"開頭的內容讀出來
peek(),ignore()
9、輸出操作cout
(1) << 操作 被輸出到螢幕上的東西,只所以能輸出,都是以字串類型輸出
也就是說這個操作有自動類型轉換的功能
(2)put() 返回cout引用,可以連續調用
(3)write(buf,len) 按指定長度寫到螢幕上 buf是char*類型
(4)cout.width(10); 列印的內容總共佔10個字元,並靠右對齊
只對其後邊的一個cout生效
(5)cout.fill('#'); 用'#'補齊空位
主要調用一次,對以後的都生效
(6)setf()操作,控制格式,教材188頁
(7)特殊字元
'\r' 表示回退一個格,再輸出
'\n' 斷行符號
\\ 輸出一個'\',因為'\'會被認為是逸出字元
'\t' 一個tab鍵
(8)輸出控制符
oct 按八進位輸出 “0”
dec 使進位輸出
hex 按十六進位輸出 “0x”
flush 清空緩衝區 帶緩衝區是因為和外部裝置交涉,這樣能減少向螢幕輸出的次數,提高效率
斷行符號、程式結束和flush都是重新整理緩衝的命令
cout << "a" <<flush ;
10、ofstream
開啟檔案,把資料寫進檔案,關閉檔案
ofstream ofs("ofstream.txt"); //開啟檔案,若檔案不存在,建立,存在,開啟 if(ofs.fail()){ //寫檔案失敗,一般是許可權問題 cout << "open file error "<<endl; return 0; }
在iostream標頭檔中cin cout對象已經被聲明,可以直接使用,因為標準輸入輸出裝置是唯一的,系統聲明
但是fstream的對象要程式員來聲明,因為對檔案的輸入輸出是不唯一的
ofstream ofs("ofstream.txt" , ios::app); //以追加的形式向檔案中寫
ios::trunc 預設 把檔案內容清空,寫新的檔案
ios::nocreate 不建立新檔案
ios::noreplace 不改寫,要建立新檔案
組合多個 ofstream ofs("ofstream.txt" , ios::app | ios::in | ios::binary);
11、讀寫二進位檔案
(1)ios::binary
(2)read/write 方法讀寫二進位檔案,因為這兩個方法只需要起始位置和大小就可以工作
作業:(1)int readInt(){}
double readDouble(){}
強轉函數,要求容錯能力強,要求有可靠的手段通知使用者是否出錯
(2)根據使用者輸入的使用者名稱,列印他的使用者id,home,shell,如果使用者不存在,通知使用者
strtok(),strcmp()