文件
標(biāo)準(zhǔn)的輸入輸出設(shè)備名有哪些?
文件輸入類的類名是?
流
原理
- cout是流的對象,它在iostream頭文件中作為全局對象定義
ostream cout(stdout)//標(biāo)準(zhǔn)設(shè)備名作為其構(gòu)造時(shí)的參數(shù)
- ostream流類對應(yīng)每個(gè)基本數(shù)據(jù)類型都有友元,它們在iostream中聲明:
ostream& operator<<(ostream& dest,char* pSource);
ostream& operator<<(ostream& dest,int source)孽锥;
ostream& operator<<(ostream& dest,char source);
- 分析語句:
cout<<"My name is Jone";
//ostream& operator<<(ostream& dest,char *pSource);
- 如果是:
cout<<"this is"<<7
//(cout<<"this is")<<7;
//ostream& operator<<(ostream& dest,int pSource);
- cin是istream的全局對象.istream流類也有若干個(gè)友元;
istream& operator>>(istream& dest话瞧,char* pSource);
istream& operator>>(istream& dest寝姿,int source)交排;
istream& operator>>(istream& dest,char source)饵筑;
- C++的類ostream提供了格式化輸出和無格式輸出的功能
- 用流插入運(yùn)算符輸出標(biāo)準(zhǔn)類型的數(shù)據(jù)埃篓;
- 用成員函數(shù)put輸出字符;
- 成員函數(shù)write的無格式化輸出根资;
- 輸出十進(jìn)制架专、八進(jìn)制同窘、十六進(jìn)制格式的整數(shù);
- 輸出各種精度的浮點(diǎn)數(shù)部脚、輸出強(qiáng)制帶有小數(shù)點(diǎn)的浮點(diǎn)數(shù)想邦,以及用科學(xué)計(jì)數(shù)法和定點(diǎn)計(jì)數(shù)法表示的浮點(diǎn)數(shù);
- 輸出在指定域?qū)拑?nèi)對齊的數(shù)據(jù)委刘;
- 輸出在域?qū)拑?nèi)用指定字符填充空位的數(shù)據(jù)丧没;
- 輸出科學(xué)計(jì)數(shù)法和十六進(jìn)制計(jì)數(shù)法中的大寫字母。
int g=0;
int fun()
{
return ++g;
}
int main(int argc, char **argv)
{
cout<<fun()<<fun()<<fun()<<fun()<<endl;
return 0;
}
//結(jié)果為:
//4321
輸出流注意事項(xiàng)
上例中輸出的順序有如下規(guī)律:
計(jì)算順序: 自右向左
輸出順序: 自左向右
cout 在執(zhí)行時(shí)相當(dāng)于一個(gè)函數(shù)锡移,而即將輸出的4 個(gè)fun( ) 函數(shù)相當(dāng)參數(shù)呕童,編譯器在函數(shù)調(diào)用時(shí)的入棧順序是從右向左的,所以在指向fun( )函數(shù)時(shí)淆珊,依次從右向左執(zhí)行拉庵,執(zhí)行完fun( )函數(shù)之后,cout輸出各個(gè)參數(shù)返回的值套蒂,此時(shí)又是從左至右進(jìn)行輸出钞支,所以函數(shù)的執(zhí)行結(jié)果為:4321
輸入流
下面我們要討論流的輸入,這是用流讀取運(yùn)算符(即重載的運(yùn)算符>>)實(shí)現(xiàn)的操刀。
- 流讀取運(yùn)算符通常會(huì)跳過輸人流中的空格烁挟、tab鍵、換行符等等的空白字符骨坑,稍后將介紹如何改變這種行為撼嗓。
- 當(dāng)遇到輸入流中的文件結(jié)束符時(shí),流讀取運(yùn)算符返回0(false);否則欢唾,流讀取運(yùn)算符返回對調(diào)用該運(yùn)算符的對象的引用且警。
- 每個(gè)輸入流都包含一組用于控制流狀態(tài)(即格式化、出錯(cuò)狀態(tài)設(shè)置等)的狀態(tài)位礁遣。
- 當(dāng)輸入類型有錯(cuò)時(shí)斑芜,流讀取運(yùn)算符就會(huì)設(shè)置輸人流的failbit狀態(tài)位;
- 如果操作失敗則設(shè)置badbit狀態(tài)位祟霍,后面會(huì)介紹如何在I/O操作后測試這些狀態(tài)位杏头。
- 最重要的輸出流
- 重要的輸入流類
- istream的其他成員
#include<iostream>
using namespace std;
int main()
{
string s;
cout<<"請輸入一個(gè)字符串:";
//1.忽略輸入緩存區(qū)中的錢八個(gè)字符
//2.在前八個(gè)字符中存在結(jié)束字符,那么就忽略
//輸入緩沖區(qū) 結(jié)束字符 之前的字符
cin.ignore(8,' ');//設(shè)置' '為結(jié)束字符
cin>>s;
cout<<"string = "<<s<<endl;
return 0;
}
//結(jié)果為
//1.請輸入一個(gè)字符串:1234567890
//string = 90
//2.請輸入一個(gè)字符串:12 345
//string = 345
#include<iostream>
using namespace std;
int main()
{
char ch;
cin.putback('a');//將字符a放入到輸入緩存流
cout<<"請輸入一個(gè)ch數(shù)據(jù):";
cin>>ch;
cout<<"ch = "<<ch<<endl;
return 0;
}
//結(jié)果為:
//請輸入一個(gè)ch數(shù)據(jù):ch = a
#include<iostream>
using namespace std;
int main()
{
int i;
string s;
//獲得輸入緩沖區(qū)中的第一個(gè)字符
cout<<"start"<<endl;
char ch=cin.peek();
cout<<"end"<<endl;
if(ch>='0'&&ch<='9')
{
cin>>i;
cout<<"int i = "<<i<<endl;
}
else
{
cin>>s;
cout<<"string s = "<<s<<endl;
}
}
//結(jié)果為:
//1.start
//123
//end
//int i = 123
//2.start
//asdf
//end
//string s = asdf
//3.start
//1qwr
//end
//int i = 1
- 調(diào)用成員函數(shù)read、write可實(shí)現(xiàn)無格式輸入/輸出沸呐。
char buffe[] =“HAPPY BIRTHDAY”醇王; cout.write(buffer, 10 );
- 成員函數(shù)read把指定個(gè)數(shù)的字符輸入到字符數(shù)組中崭添。成員函數(shù)gcount統(tǒng)計(jì)最后輸入的字符個(gè)數(shù)寓娩。
cin.read( buffer, 20 ); //讀入20個(gè)字符
cout.write( buffer, cin.gcount() ); //輸出輸入的所有字符
流操作算子
int i=11;
cout<<hex<<i<<endl;//結(jié)果為:b(轉(zhuǎn)換為十六進(jìn)制)
cout<<oct<<i<<endl;//結(jié)果為:13(轉(zhuǎn)換為8進(jìn)制)
cout<<hex<<i<<" "<<dec<<14<<endl;//結(jié)果為:b 14
return 0;
#include<iostream>
#include<iomanip>
using namespace std;
int main()
{
int i=11;
cout<<hex<<i<<" "<<dec<<14<<endl;
cout<<setbase(8)<<i<<endl;
return 0;
}
//結(jié)果為:
//b 14
//13
#include<iostream>
#include<iomanip>
using namespace std;
int main()
{
int i=11;
// cout<<hex<<i<<endl;//結(jié)果為:b(轉(zhuǎn)換為十六進(jìn)制)
// cout<<oct<<i<<endl;//結(jié)果為:13(轉(zhuǎn)換為8進(jìn)制)
cout<<hex<<i<<" "<<dec<<i<<endl;
cout<<setbase(8)<<i<<endl;
return 0;
}
//結(jié)果為:
//b 11
//13
#include<iostream>
#include<iomanip>
using namespace std;
int main()
{
int i=11;
cout<<hex<<i<<" "<<dec<<i<<endl;
cout<<setbase(16)<<i<<endl;
return 0;
}
//結(jié)果為:
//b 11
//b
- 可以用流操縱算子setprecision或成員函數(shù)percision控制小數(shù)點(diǎn)后面的位數(shù)。
- 設(shè)置了精度以后,該精度對之后所有的輸出操作都有效棘伴,直到下一次設(shè)置精度為止寞埠。
- 無參數(shù)的成員函數(shù)percision返回當(dāng)前設(shè)置的精度。
#include<iostream>
#include<iomanip>
using namespace std;
int main()
{
double root2=3.14159265;
for(int places=0;places<=9;places++)
{
cout<<setprecision(places)<<root2<<"\n";
}
return 0;
}
//結(jié)果為:
//3
//3
//3.1
//3.14
//3.142
//3.1416
//3.14159
//3.141593
//3.1415927
//3.14159265
- 成員函數(shù)ios.width設(shè)置當(dāng)前的域?qū)?即輸入輸出的字符數(shù))并返回以前設(shè)置的域?qū)挕?/li>
- 如果顯示數(shù)據(jù)所需的寬度比設(shè)置的域?qū)捫∨畔樱瘴挥锰畛渥址畛洹?br>
?3. 如果顯示數(shù)據(jù)所需的寬度比設(shè)置的域?qū)挻?顯示數(shù)據(jù)并不會(huì)被截?cái)啵到y(tǒng)會(huì)輸出所有位缰犁。
- 域?qū)捲O(shè)置僅對下一行流讀取或流插入操作有效淳地,在一次操作完成之后,城寬又被置回0
- 未對所處理的輸出數(shù)據(jù)提供足夠的域?qū)挄r(shí)帅容,輸出數(shù)據(jù)將按需要的域?qū)掃M(jìn)行輸出颇象,有可能產(chǎn)生難以閱讀的輸出結(jié)果。
#include<iostream>
#include<iomanip>
using namespace std;
int main()
{
int t1[5]={12345,1,3333,22,999};
int t2[5]={2,22,333,4444,55};
for(int i=0;i<5;i++)
{
cout.width(6);
cout<<t1[i];
}
cout<<endl;
for(int j=0;j<5;j++)
{
cout.width(6);
cout<<t2[j];
}
cout<<endl;
return 0;
}
//結(jié)果為:
//12345 1 3333 22 999
// 2 22 333 4444 55
#include<iostream>
#include<iomanip>
using namespace std;
int main()
{
char n[30]={0};
cin.width(5);
while(cin>>n)
{
cout<<"n = "<<n<<endl;
cin.width(5);
}
return 0;
}
//結(jié)果為:
//(1)1234
//n = 1234
//(2)12345
//n = 1234
//n = 5
//(3)1234567890123
//n = 1234
//n = 5678
//n = 9012
//n = 3
#include<iostream>
#include<iomanip>
using namespace std;
ostream& tab(ostream& output )
{
return output<<'\t';
}
int main()
{
cout<<'a'<<tab<<'b'<<'\t'<<'c'<<endl;
return 0;
}
//結(jié)果為:
//a b c
文件指針
驗(yàn)證流狀態(tài)
bool bad( )//讀寫的過程中出錯(cuò)并徘,返回true
bool fail( )//讀寫的過程出錯(cuò)遣钳,或者格式讀取錯(cuò)誤也會(huì)返回true
bool eof( //讀文件到末尾時(shí),返回true
bool good( )//文件讀寫正常返回true
//若想重置以上成員函數(shù)檢查的狀態(tài)標(biāo)志麦乞,可以使用clear( ) 函數(shù)
#include<iostream>
#include<iomanip>
using namespace std;
#include<limits>
int main()
{
int a;
int b;
cin>>a;
cout<<"a = "<<a<<endl;
cout<<"cin1 = "<<cin.good()<<endl;
if(!cin.good())
{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(),'\n');
}
cout<<"cin2 = "<<cin.good()<<endl;
cin>>b;
cout<<"b = "<<b<<endl;
return 0;
}
//結(jié)果為:
//(1)g
//a = 0
//cin1 = 0
//cin2 = 1
//12
//b = 12
//(2)12
//a = 12
//cin1 = 1
//cin2 = 1
//23
//b = 23
文件打開
- 使用構(gòu)造函數(shù)打開
創(chuàng)建流對象時(shí)直接打開文件
eg: ofstream ofile(const char *filename, openmode);
- 使用成員函數(shù)open打開文件
eg: ofstream ofile;
ofile.open(const char *filename, openmode)
openmode文件打開模式
- ios::in 輸入(讀)模式打開文件
- ios:: out輸出(寫)模式打開文件
- ios::app追加模式打開文件
- ios::trunc若文件已經(jīng)存在則清空文件的模式打開文件
- ios::binary 二進(jìn)制方式打開文件
- 這些標(biāo)識可以單獨(dú)使用蕴茴,也可以組合使用,中間用”或“ 運(yùn)算符 ”|“ 間隔姐直。
fstream file;
file.open(“example”, ios::out | ios::app | ios::binary);
文件類的默認(rèn)打開方式
打開文件時(shí)倦淀,沒有指定打開模式時(shí),使用默認(rèn)的打開方式声畏;
- ofstream: ios:: out | ios::trunc
- ifstream: ios:: in
- fstream: ios:: in | ios:: out
對于ifstream 的流對象在打開文件時(shí)即使指定的模式中沒有顯示的標(biāo)明ios::in 模式撞叽,ios::in 標(biāo)識也一直存在
#include<iomanip>
using namespace std;
#include<fstream>
int main()
{
ifstream ifile("/home/jiangxiubi/1612/jxb");
char sztext[20];
double price;
ifile>>sztext>>price;
cout<<sztext<<" "<<price;
ifile.close()
/*ofstream ofile("/home/jiangxiubi/1612/jxb");
ofile<<"pear"<<" "<<4.5;
ofile.close();*/
return 0;
}
//結(jié)果為:在文件jxb中顯示pear 4.5
#include<iostream>
#include<iomanip>
using namespace std;
#include<fstream>
int main()
{
ifstream ifile("/home/jiangxiubi/1612/jxb1",ios::in|ios::binary);
char temp[20];
ifile.read(temp,20);
cout<<temp<<endl;
ifile.close();
/* ofstream ofile("/home/jiangxiubi/1612/jxb1",ios::out|ios::binary);
char temp[20]="nihao";
ofile.write(temp,20);
ofile.close();*/
return 0;
}
文件關(guān)閉
- 當(dāng)文件的讀寫操作完成之后,我們必須將文件關(guān)閉以使文件重新變?yōu)榭稍L問的插龄。關(guān)閉文件時(shí)需要調(diào)用成員函數(shù)close( ),它負(fù)責(zé)將緩存中的數(shù)據(jù)排放出來并關(guān)閉文件愿棋。
- 這個(gè)函數(shù)一旦被調(diào)用,原來的流對象就可以被用來打開其他的文件了均牢,這個(gè)文件也可以重新被其他的進(jìn)程訪問了糠雨。
#include<fstream>
fstream file;
file.open(“example”, ios::out | ios::app | ios::binary);
if(file !=NULL) {
cout<<“open failed”<<endl;
}
//……. 文件操作
file.close();
文件指針
流指針相關(guān)函數(shù)
- tellg( )和 tellp( )
返回一個(gè)pos_type類型,即整數(shù)徘跪,分別代表當(dāng)前讀指針(get) 和 寫指針(put) 的位置
- seekg( pos_type position ) 和 seekp( pos_type position )
流指針被改變?yōu)橹赶蛭募_始計(jì)算的一個(gè)絕對位置见秤,傳入的參數(shù)類型與函數(shù)tellg 和 tellp 的返回值類型相同
- seekg( offset, seekdir) 和 seekp( offset, seekdir)
從由參數(shù)seekdir 設(shè)定的位置開始計(jì)算一個(gè)位移 offset,其中seekdir的值可以是: ios::beg(流開始的位置),ios::cur(流當(dāng)前的位置)真椿,ios::end(流末尾的位置)
#include<iostream>
#include<fstream>
using namespace std;
int main()
{
ifstream ifile("/home/jiangxiubi/1612/jxb.txt");
if(NULL==ifile)
{
cout<<"打開文件失敗"<<endl;
return -1;
}
//定位函數(shù) -get指針(讀指針)
ifile.seekg(0,ios::end);
//指針位置函數(shù) -get 指針(讀指針)
cout<<"get point position:"<<ifile.tellg()<<endl;
ifile.close();
return 0;
}
extern
extern “ C ”
extern 是c/c++
- 語言中表明函數(shù)或全局變量作用范圍的關(guān)鍵字鹃答,該關(guān)鍵字告訴編譯器此,其聲明的函數(shù)和變量可以在本模塊或其他模塊中使用
在c++的環(huán)境下使用c
- 的函數(shù)時(shí)突硝,通常會(huì)出現(xiàn)編譯器無法找到 obj 模塊中的c 函數(shù)定義的問題测摔,從而導(dǎo)致鏈接失敗。這時(shí)因?yàn)樵赾++ 中支持函數(shù)重載,編譯時(shí)會(huì)將函數(shù)名和參數(shù)列表連接起來锋八,而c 語言不會(huì)浙于,因此會(huì)造成鏈接失敗的情況,此時(shí) c 函數(shù)就需要使用extern “C “ 來進(jìn)行鏈接指定