C++IO和文件操作

文件

標(biāo)準(zhǔn)的輸入輸出設(shè)備名有哪些?

文件輸入類的類名是?

  • Iostream

原理

  • 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);


  1. 分析語句:
cout<<"My name is Jone";
//ostream& operator<<(ostream& dest,char *pSource);

  1. 如果是:
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)饵筑;

  1. 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)的操刀。

  1. 流讀取運(yùn)算符通常會(huì)跳過輸人流中的空格烁挟、tab鍵、換行符等等的空白字符骨坑,稍后將介紹如何改變這種行為撼嗓。
  2. 當(dāng)遇到輸入流中的文件結(jié)束符時(shí),流讀取運(yùn)算符返回0(false);否則欢唾,流讀取運(yùn)算符返回對調(diào)用該運(yùn)算符的對象的引用且警。
  3. 每個(gè)輸入流都包含一組用于控制流狀態(tài)(即格式化、出錯(cuò)狀態(tài)設(shè)置等)的狀態(tài)位礁遣。
  4. 當(dāng)輸入類型有錯(cuò)時(shí)斑芜,流讀取運(yùn)算符就會(huì)設(shè)置輸人流的failbit狀態(tài)位;
  5. 如果操作失敗則設(shè)置badbit狀態(tài)位祟霍,后面會(huì)介紹如何在I/O操作后測試這些狀態(tài)位杏头。
  1. 最重要的輸出流
  • ostream
  • ofstream
  1. 重要的輸入流類
  • istream
  • ifstream
  1. istream的其他成員
  • ignore
#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

  • putback
#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

  • peek
#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

  • 設(shè)置浮點(diǎn)數(shù)精度
  1. 可以用流操縱算子setprecision或成員函數(shù)percision控制小數(shù)點(diǎn)后面的位數(shù)。
  2. 設(shè)置了精度以后,該精度對之后所有的輸出操作都有效棘伴,直到下一次設(shè)置精度為止寞埠。
  3. 無參數(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è)置域?qū)?/li>
  1. 成員函數(shù)ios.width設(shè)置當(dāng)前的域?qū)?即輸入輸出的字符數(shù))并返回以前設(shè)置的域?qū)挕?/li>
  2. 如果顯示數(shù)據(jù)所需的寬度比設(shè)置的域?qū)捫∨畔樱瘴挥锰畛渥址畛洹?br> ?3. 如果顯示數(shù)據(jù)所需的寬度比設(shè)置的域?qū)挻?顯示數(shù)據(jù)并不會(huì)被截?cái)啵到y(tǒng)會(huì)輸出所有位缰犁。
  3. 域?qū)捲O(shè)置僅對下一行流讀取或流插入操作有效淳地,在一次操作完成之后,城寬又被置回0
  4. 未對所處理的輸出數(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


文件打開

  1. 使用構(gòu)造函數(shù)打開
創(chuàng)建流對象時(shí)直接打開文件
    eg: ofstream ofile(const char *filename, openmode);
    
  1. 使用成員函數(shù)open打開文件
    eg: ofstream ofile;
     ofile.open(const char *filename, openmode)
     

openmode文件打開模式

  1. ios::in 輸入(讀)模式打開文件
  2. ios:: out輸出(寫)模式打開文件
  3. ios::app追加模式打開文件
  4. ios::trunc若文件已經(jīng)存在則清空文件的模式打開文件
  5. 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)的打開方式声畏;

  1. ofstream: ios:: out | ios::trunc
  2. ifstream: ios:: in
  3. 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)閉

  1. 當(dāng)文件的讀寫操作完成之后,我們必須將文件關(guān)閉以使文件重新變?yōu)榭稍L問的插龄。關(guān)閉文件時(shí)需要調(diào)用成員函數(shù)close( ),它負(fù)責(zé)將緩存中的數(shù)據(jù)排放出來并關(guān)閉文件愿棋。
  2. 這個(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ù)

  1. tellg( )和 tellp( )
    返回一個(gè)pos_type類型,即整數(shù)徘跪,分別代表當(dāng)前讀指針(get) 和 寫指針(put) 的位置
  1. seekg( pos_type position ) 和 seekp( pos_type position )
    流指針被改變?yōu)橹赶蛭募_始計(jì)算的一個(gè)絕對位置见秤,傳入的參數(shù)類型與函數(shù)tellg 和 tellp 的返回值類型相同
  1. 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)行鏈接指定
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末挟纱,一起剝皮案震驚了整個(gè)濱河市羞酗,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌紊服,老刑警劉巖檀轨,帶你破解...
    沈念sama閱讀 222,865評論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異欺嗤,居然都是意外死亡参萄,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,296評論 3 399
  • 文/潘曉璐 我一進(jìn)店門煎饼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來讹挎,“玉大人,你說我怎么就攤上這事吆玖⊥怖#” “怎么了?”我有些...
    開封第一講書人閱讀 169,631評論 0 364
  • 文/不壞的土叔 我叫張陵沾乘,是天一觀的道長铡羡。 經(jīng)常有香客問我,道長意鲸,這世上最難降的妖魔是什么烦周? 我笑而不...
    開封第一講書人閱讀 60,199評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮怎顾,結(jié)果婚禮上读慎,老公的妹妹穿的比我還像新娘。我一直安慰自己槐雾,他們只是感情好夭委,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,196評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著募强,像睡著了一般株灸。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上擎值,一...
    開封第一講書人閱讀 52,793評論 1 314
  • 那天慌烧,我揣著相機(jī)與錄音,去河邊找鬼鸠儿。 笑死屹蚊,一個(gè)胖子當(dāng)著我的面吹牛厕氨,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播汹粤,決...
    沈念sama閱讀 41,221評論 3 423
  • 文/蒼蘭香墨 我猛地睜開眼命斧,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了嘱兼?” 一聲冷哼從身側(cè)響起国葬,我...
    開封第一講書人閱讀 40,174評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎芹壕,沒想到半個(gè)月后汇四,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,699評論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡哪雕,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,770評論 3 343
  • 正文 我和宋清朗相戀三年船殉,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了鲫趁。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片斯嚎。...
    茶點(diǎn)故事閱讀 40,918評論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖挨厚,靈堂內(nèi)的尸體忽然破棺而出堡僻,到底是詐尸還是另有隱情,我是刑警寧澤疫剃,帶...
    沈念sama閱讀 36,573評論 5 351
  • 正文 年R本政府宣布钉疫,位于F島的核電站,受9級特大地震影響巢价,放射性物質(zhì)發(fā)生泄漏牲阁。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,255評論 3 336
  • 文/蒙蒙 一壤躲、第九天 我趴在偏房一處隱蔽的房頂上張望城菊。 院中可真熱鬧,春花似錦碉克、人聲如沸凌唬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,749評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽客税。三九已至,卻和暖如春撕贞,著一層夾襖步出監(jiān)牢的瞬間更耻,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,862評論 1 274
  • 我被黑心中介騙來泰國打工捏膨, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留酥夭,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,364評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像熬北,于是被迫代替她去往敵國和親疙描。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,926評論 2 361

推薦閱讀更多精彩內(nèi)容