国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
C++中的文件輸入/輸出(3):掌握輸入/輸出流

C++中的文件輸入/輸出(3)

原作:Ilia Yordanov,  loobian@cpp-home.com

 

掌握輸入/輸出流

 

在這一章里,我會(huì)提及一些有用的函數(shù)。我將為你演示如何打開一個(gè)可以同時(shí)進(jìn)行讀、寫操作的文件;此外,我還將為你介紹其它打開文件的方法,以及如何判斷打開操作是否成功。因此,請接著往下讀!

到目前為止,我已為你所展示的只是單一的打開文件的途徑:要么為讀取而打開,要么為寫入而打開。但文件還可以以其它方式打開。迄今,你應(yīng)當(dāng)已經(jīng)認(rèn)識(shí)了下面的方法:

 

ifstream OpenFile(“cpp-home.txt”);

 

噢,這可不是唯一的方法!正如以前所提到的,以上的代碼創(chuàng)建一個(gè)類ifstream的對象,并將文件的名字傳遞給它的構(gòu)造函數(shù)。但實(shí)際上,還存在有不少的重載的構(gòu)造函數(shù),它們可以接受不止一個(gè)的參數(shù)。同時(shí),還有一個(gè)open()函數(shù)可以做同樣的事情。下面是一個(gè)以上代碼的示例,但它使用了open()函數(shù):

 

ifstream OpenFile;

OpenFile.open(“cpp-home.txt”);

 

你會(huì)問:它們之間有什么區(qū)別嗎?哦,我曾做了不少測試,結(jié)論是沒有區(qū)別!只不過如果你要?jiǎng)?chuàng)建一個(gè)文件句柄但不想立刻給它指定一個(gè)文件名,那么你可以使用open()函數(shù)過后進(jìn)行指定。順便再給出一個(gè)要使用open()函數(shù)的例子:如果你打開一個(gè)文件,然后關(guān)閉了它,又打算用同一個(gè)文件句柄打開另一個(gè)文件,這樣一來,你將需要使用open()函數(shù)。

考慮以下的代碼示例:

 

#include <fstream.h>

 

void read(ifstream &T) //pass the file stream to the function

{  

//the method to read a file, that I showed you before

    char ch;

 

    while(!T.eof())

    {

       T.get(ch);

       cout << ch;

    }

   

    cout << endl << "--------" << endl;

}

 

void main()

{

    ifstream T("file1.txt");

    read(T);

    T.close();

 

    T.open("file2.txt");

    read(T);

    T.close();

}

 

據(jù)此,只要file1.txtfile2.txt并存儲(chǔ)了文本內(nèi)容,你將看到這些內(nèi)容。

現(xiàn)在,該向你演示的是,文件名并不是你唯一可以向open()函數(shù)或者構(gòu)造函數(shù)(其實(shí)都一樣)傳遞的參數(shù)。下面是一個(gè)函數(shù)原型:

 

ifstream OpenFile(char *filename, int open_mode);

 

你應(yīng)當(dāng)知道filename表示文件的名稱(一個(gè)字符串),而新出現(xiàn)的則是open_mode(打開模式)。open_mode的值用來定義以怎樣的方式打開文件。下面是打開模式的列表:

名稱

描述

ios::in

打開一個(gè)可讀取文件

ios::out

打開一個(gè)可寫入文件

ios::app

你寫入的所有數(shù)據(jù)將被追加到文件的末尾,此方式使用ios::out

ios::ate

你寫入的所有數(shù)據(jù)將被追加到文件的末尾,此方式不使用ios::out

ios::trunk

刪除文件原來已存在的內(nèi)容(清空文件)

ios::nocreate

如果要打開的文件并不存在,那么以此參數(shù)調(diào)用open()函數(shù)將無法進(jìn)行。

ios::noreplace

如果要打開的文件已存在,試圖用open()函數(shù)打開時(shí)將返回一個(gè)錯(cuò)誤。

ios::binary

以二進(jìn)制的形式打開一個(gè)文件。

 

實(shí)際上,以上的值都屬于一個(gè)枚舉類型的int常量。但為了讓你的編程生涯不至于太痛苦,你可以像上表所見的那樣使用那些名稱。

下面是一個(gè)關(guān)于如何使用打開模式的例子:

 

#include <fstream.h>

 

void main()

{

    ofstream SaveFile("file1.txt", ios::ate);

 

    SaveFile << "That‘s new!\n";

 

    SaveFile.close();

}

 

正如你在表中所看到的:使用ios::ate將會(huì)從文件的末尾開始執(zhí)行寫入。如果我沒有使用它,原來的文件內(nèi)容將會(huì)被重新寫入的內(nèi)容覆蓋掉。不過既然我已經(jīng)使用了它,那么我只會(huì)在原文件的末尾進(jìn)行添加。所以,如果file1.txt原有的內(nèi)容是這樣:

Hi! This is test from www.cpp-home.com!

那么執(zhí)行上面的代碼后,程序?qū)?huì)為它添上That’s new!,因此它看起來將變成這樣:

Hi! This is test from www.cpp-home.com!That’s new!

假如你打算設(shè)置不止一個(gè)的打開模式標(biāo)志,只須使用OR操作符或者是 | ,像這樣:

 

ios::ate | ios::binary

 

我希望現(xiàn)在你已經(jīng)明白“打開模式”是什么意思了!

現(xiàn)在,是時(shí)候向你展示一些真正有用的東西了!我敢打賭你現(xiàn)在還不知道應(yīng)當(dāng)怎樣打開一個(gè)可以同時(shí)進(jìn)行讀取和寫入操作的文件!下面就是實(shí)現(xiàn)的方法:

 

fstream File(“cpp-home.txt”,ios::in | ios::out);

 

實(shí)際上,這只是一個(gè)聲明語句。我將在下面數(shù)行之后給你一個(gè)代碼示例。但此時(shí)我首先想提及一些你應(yīng)當(dāng)知道的內(nèi)容。

上面的代碼創(chuàng)建了一個(gè)名為File流式文件的句柄。如你所知,它是fstream類的一個(gè)對象。當(dāng)使用fstream時(shí),你應(yīng)當(dāng)指定ios::inios::out作為文件的打開模式。這樣,你就可以同時(shí)對文件進(jìn)行讀、寫,而無須創(chuàng)建新的文件句柄。噢,當(dāng)然,你也可以只進(jìn)行讀或者寫的操作。那樣的話,相應(yīng)地你應(yīng)當(dāng)只使用ios::in或者只使用ios::out —— 要思考的問題是:如果你打算這么做,為什么你不分別用ifstreamofstream來實(shí)現(xiàn)呢?

下面就先給出示例代碼:

 

#include <fstream.h>

 

void main()
{

    fstream File("test.txt",ios::in | ios::out);

 

    File << "Hi!"; //將“Hi!”寫入文件   

    static char str[10]; //當(dāng)使用static時(shí),數(shù)組會(huì)自動(dòng)被初始化

                //即是被清空為零


    File.seekg(ios::beg); // 回到文件首部

                  // 此函數(shù)將在后面解釋

    File >> str;

    cout << str << endl;

 

    File.close();
}

 

OK,這兒又有一些新東西,所以我將逐行進(jìn)行解釋:

 

fstream File(“test.txt”, ios::in | ios::out); —— 此行創(chuàng)建一個(gè)fstream對象,執(zhí)行時(shí)將會(huì)以讀/寫方式打開test.txt文件。這意味著你可以同時(shí)讀取文件并寫入數(shù)據(jù)。

 

File << “Hi!”; —— 我打賭你已經(jīng)知道它的意思了。

 

static char str[10]; —— 這將創(chuàng)建一個(gè)容量為10的字符數(shù)組。我猜static對你而言或者有些陌生,如果這樣就忽略它。這只不過會(huì)在創(chuàng)建數(shù)組的同時(shí)對其進(jìn)行初始化。

 

File.seekg(ios::beg); —— OK,我要讓你明白它究竟會(huì)做些什么,因此我將以一些有點(diǎn)兒離題、但挺重要的內(nèi)容開始我的解釋。

還記得它么:

 

while(!OpenFile.eof())

    {

       OpenFile.get(ch);

       cout << ch;

    }

 

你是不是曾經(jīng)很想知道那背后真正執(zhí)行了什么操作?不管是或不是,我都將為你解釋。這是一個(gè)while型循環(huán),它會(huì)一直反復(fù),直至程序的操作到達(dá)文件的尾端。但這個(gè)循環(huán)如何知道是否已經(jīng)到了文件末尾?嗯,當(dāng)你讀文件的時(shí)候,會(huì)有一個(gè)類似于“內(nèi)置指針(inside-pointer的東西,它表明你讀?。▽懭胍惨粯樱┮呀?jīng)到了文件的哪個(gè)位置,就像記事本中的光標(biāo)。而每當(dāng)你調(diào)用OpenFile.get(ch)的時(shí)候,它會(huì)返回當(dāng)前位置的字符,存儲(chǔ)在ch變量中,并將這一內(nèi)置指針向前移動(dòng)一個(gè)字符。因此下次該函數(shù)再被調(diào)用時(shí),它將會(huì)返回下一個(gè)字符。而這一過程將不斷反復(fù),直到讀取到達(dá)文件尾。所以,讓我們回到那行代碼:函數(shù)seekg()將把內(nèi)置指針定位到指定的位置(依你決定)。你可以使用:

 

ios::beg —— 可將它移動(dòng)到文件首端

ios::end —— 可將它移動(dòng)到文件末端

 

或者,你可以設(shè)定向前或向后跳轉(zhuǎn)的字符數(shù)。例如,如果你要向定位到當(dāng)前位置的5個(gè)字符以前,你應(yīng)當(dāng)寫:

File.seekg(-5);

如果你想向后跳過40個(gè)字符,則應(yīng)當(dāng)寫:

File.seekg(40);

同時(shí),我必須指出,函數(shù)seekg()是被重載的,它也可以帶兩個(gè)參數(shù)。另一個(gè)版本是這樣子的:

File.seekg(-5,ios::end);

在這個(gè)例子中,你將能夠讀到文件文本的最后4個(gè)字符,因?yàn)椋?/span>

1)你先到達(dá)了末尾(ios::end

2)你接著到達(dá)了末尾的前五個(gè)字符的位置(-5

為什么你會(huì)讀到4個(gè)字符而不是5個(gè)?噢,只須把最后一個(gè)看成是“丟掉了”,因?yàn)槲募钅┒说?#8220;東西”既不是字符也不是空白符,那只是一個(gè)位置(譯注:或許ios::end所“指”的根本已經(jīng)超出了文件本身的范圍,確切的說它是指向文件最后一個(gè)字符的下一個(gè)位置,有點(diǎn)類似STL中的各個(gè)容器的end迭代點(diǎn)是指向最后一個(gè)元素的下一位置。這樣設(shè)計(jì)可能是便于在循環(huán)中實(shí)現(xiàn)遍歷)。

你現(xiàn)在可能想知道為什么我要使用到這個(gè)函數(shù)。呃,當(dāng)我把“Hi”寫進(jìn)文件之后,內(nèi)置指針將被設(shè)為指向其后面……也就是文件的末尾。因此我必須將內(nèi)置指針設(shè)回文件起始處。這就是這個(gè)函數(shù)在此處的確切用途。

File >> str; —— 這也是新鮮的玩意兒!噢,我確信這行代碼讓你想起了cin >> .實(shí)際上,它們之間有著相當(dāng)?shù)年P(guān)聯(lián)。此行會(huì)從文件中讀取一個(gè)單詞,然后將它存入指定的數(shù)組變量中。

例如,如果文件中有這樣的文本片斷:

Hi! Do you know me?

使用File >> str,則只會(huì)將“Hi!”輸出到str數(shù)組中。你應(yīng)當(dāng)已經(jīng)注意到了,它實(shí)際上是將空格作為單詞的分隔符進(jìn)行讀取的。

由于我存入文件中的只是單獨(dú)一個(gè)Hi!,我不需要寫一個(gè)while循環(huán),那會(huì)花費(fèi)更多的時(shí)間來寫代碼。這就是我使用此方法的原因。順便說一下,到目前為止,我所使用的讀取文件的while循環(huán)中,程序讀文件的方式是一個(gè)字符一個(gè)字符進(jìn)行讀取的。然而你也可以一個(gè)單詞一個(gè)單詞地進(jìn)行讀取,像這樣:

 

char str[30]; // 每個(gè)單詞的長度不能超過30個(gè)字符

while(!OpenFile.eof())

    {

       OpenFile >> str;

       cout << str;

    }

 

你也可以一行一行地進(jìn)行讀取,像這樣:

 

char line[100]; // 每個(gè)整行將會(huì)陸續(xù)被存儲(chǔ)在這里
while(!OpenFile.eof())
{

OpenFile.getline(line,100); // 100是數(shù)組的大小

cout << line << endl;
}

 

你現(xiàn)在可能想知道應(yīng)當(dāng)使用哪種方法。嗯,我建議你使用逐行讀取的方式,或者是最初我提及的逐字符讀取的方式。而逐詞讀取的方式并非一個(gè)好的方案,因?yàn)樗粫?huì)讀出新起一行這樣的信息,所以如果你的文件中新起一行時(shí),它將不會(huì)將那些內(nèi)容新起一行進(jìn)行顯示,而是加在已經(jīng)打印的文本后面。而使用getline()或者get()都將會(huì)向你展現(xiàn)出文件的本來面目!

現(xiàn)在,我將向你介紹如何檢測文件打開操作是否成功。實(shí)現(xiàn)上,好的方法少之又少,我將都會(huì)涉及它們。需要注意的是,出現(xiàn)“X”的時(shí)候,它實(shí)際可以以“o” “i”來代替,或者也可以什么都不是(那將是一個(gè)fstream對象)。

1:最通常的作法

 

Xfstream File(“cpp-home.txt”);

if (!File)
{

cout << “Error opening the file! Aborting…\n”;

exit(1);
}

 

 

2:如果文件已經(jīng)被創(chuàng)建,返回一個(gè)錯(cuò)誤

 

ofstream File("unexisting.txt", ios::nocreate);

 

if(!File)

{

cout << “Error opening the file! Aborting…\n”;

exit(1);

}

 

3:使用fail()函數(shù)

 

ofstream File("filer.txt", ios::nocreate);

 

if(File.fail())

{

cout << “Error opening the file! Aborting…\n”;

exit(1);

}

 

3中的新出現(xiàn)的東西,是fail()函數(shù)。如果有任何輸入/輸出錯(cuò)誤(不是在文件末尾)發(fā)生,它將返回非零值。

我也要講一些我認(rèn)為非常重要的內(nèi)容!例如,如果你已經(jīng)創(chuàng)建一個(gè)流文件對象,但你沒有進(jìn)行打開文件操作,像這樣:

 

ifstream File; //也可以是一個(gè)ofstream

 

這樣,我們就擁有一個(gè)文件句柄,但我們?nèi)匀粵]有打開文件。如果你打算遲些打開它,那么可以用open()函數(shù)來實(shí)現(xiàn),我已經(jīng)在本教程中將它介紹了。但如果在你的程序的某處,你可能需要知道當(dāng)前的句柄是否關(guān)聯(lián)了一個(gè)已經(jīng)打開的文件,那么你可以用is_open()來進(jìn)行檢測。如果文件沒有打開,它將返回0 (false);如果文件已經(jīng)打開,它將返回1 (true)。例如:

 

ofstream File1;

File1.open("file1.txt");

cout << File1.is_open() << endl;

 

上面的代碼將會(huì)返回1(譯注:指File1.is_open()函數(shù),下句同),因?yàn)槲覀円呀?jīng)打開了一個(gè)文件(在第二行)。而下面的代碼則會(huì)返回0,這是由于我們沒有打開文件,而只是創(chuàng)建了一個(gè)流文件句柄:

ofstream File1;

cout << File1.is_open() << endl;

好啦,這一章講得夠多啦。



本文引用通告地址: http://blog.csdn.net/Kusk/services/trackbacks/7379.aspx
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
c++文件操作詳解
UC頭條:c 如何創(chuàng)建、修改及刪除文件
C++之文件IO操作流
C++方式的文件操作(1)
C++中輸入輸出流及文件流操作筆記
c/C++ 文件讀寫 收集備用
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服