日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C 和 C++ 文件操作详解

發(fā)布時間:2024/7/23 c/c++ 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C 和 C++ 文件操作详解 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

?

來源:http://www.cnblogs.com/likebeta/archive/2012/06/16/2551662.html

來源:http://www.cnblogs.com/likebeta/archive/2012/06/16/2551780.html

?

?

?

CPP 的文件操作

?

在C++中,有一個stream這個類,所有的I/O都以這個“流”類為基礎(chǔ)的,包括我們要認識的文件I/O,stream這個類有兩個重要的運算符:

1、插入器(<<)
  向流輸出數(shù)據(jù)。比如說系統(tǒng)有一個默認的標(biāo)準(zhǔn)輸出流(cout),一般情況下就是指的顯示器,所以,cout<<"Write Stdout"<<''\n'';就表示把字符串"Write Stdout"和換行字符(''\n'')輸出到標(biāo)準(zhǔn)輸出流。

2、析取器(>>)
  從流中輸入數(shù)據(jù)。比如說系統(tǒng)有一個默認的標(biāo)準(zhǔn)輸入流(cin),一般情況下就是指的鍵盤,所以,cin>>x;就表示從標(biāo)準(zhǔn)輸入流中讀取一個指定類型(即變量x的類型)的數(shù)據(jù)。
  在C++中,對文件的操作是通過stream的子類fstream(file stream)來實現(xiàn)的,所以,要用這種方式操作文件,就必須加入頭文件fstream.h。

C++ 通過以下幾個類支持文件的輸入輸出:

  • ofstream: 寫操作(輸出)的文件類 (由ostream引申而來)
  • ifstream: 讀操作(輸入)的文件類(由istream引申而來)
  • fstream: 可同時讀寫操作的文件類 (由iostream引申而來)

?

?

打開文件(Open a file)

對這些類的一個對象所做的第一個操作通常就是將它和一個真正的文件聯(lián)系起來,也就是說打開一個文件。被打開的文件在程序中由一個流對象(stream object)來表示 (這些類的一個實例) ,而對這個流對象所做的任何輸入輸出操作實際就是對該文件所做的操作。

?

1. 通過一個流對象調(diào)用open函數(shù)打開一個文件。

我們使用它的成員函數(shù)open():void open (const char * filename, openmode mode);

這里filename 是一個字符串,代表要打開的文件名,mode 是以下標(biāo)志符的一個組合: ios::in 為輸入(讀)而打開文件

文件的輸入輸出是從內(nèi)存的角度看的:數(shù)據(jù)載入內(nèi)存叫做輸入,數(shù)據(jù)從內(nèi)存到其他地方叫做輸出。

  • ios::out?文件以輸出(寫)方式打開?
  • ios::in ? ?文件以輸入(讀)方式打開
  • ios::ate 初始位置:文件尾
  • ios::app 所有輸出附加在文件末尾
  • ios::trunc 如果文件已存在則先刪除該文件
  • ios::binary 二進制方式

這些標(biāo)識符可以被組合使用,中間以”或”操作符(|)間隔。例如,如果我們想要以二進制方式打開文件”example.bin” 來寫入一些數(shù)據(jù),我們可以通過以下方式調(diào)用成員函數(shù)open()來實現(xiàn):

ofstream file; file.open ("example.bin", ios::out | ios::app | ios::binary);

ofstream, ifstream 和 fstream所有這些類的成員函數(shù)open 都包含了一個默認打開文件的方式,這三個類的默認方式各不相同: 類 參數(shù)的默認方式

  • ofstream ios::out | ios::trunc
  • ifstream ios::in
  • fstream ios::in | ios::out

只有當(dāng)函數(shù)被調(diào)用時沒有聲明方式參數(shù)的情況下,默認值才會被采用。如果函數(shù)被調(diào)用時聲明了任何參數(shù),默認值將被完全改寫,而不會與調(diào)用參數(shù)組合。

?

2. 通過 類 對象 構(gòu)造函數(shù) 打開文件。

類 ofstream, ifstream 和 fstream 的 對象 所進行的第一個操作通常都是打開文件,這些類都有一個構(gòu)造函數(shù)可以直接調(diào)用open 函數(shù),并擁有同樣的參數(shù)。這樣,我們就可以通過以下方式進行與上面同樣的定義對象和打開文件的操作:

ofstream file ("example.bin", ios::out | ios::app | ios::binary); 例如:以二進制輸入方式打開文件c:\config.sys fstream file1; file1.open("c:\\config.sys",ios::binary|ios::in,0);//如果open函數(shù)只有文件名一個參數(shù),則是以讀/寫普通文件打開,即: file1.open("c:\\config.sys");<=>file1.open("c:\\config.sys",ios::in|ios::out,0);//另外,fstream還有和open()一樣的構(gòu)造函數(shù),對于上例,在定義的時侯就可以打開文件了: fstream file1("c:\\config.sys");

以上 兩種 打開文件的方式都是正確的。

?

通過調(diào)用成員函數(shù)is_open()來檢查一個文件是否已經(jīng)被順利的打開:bool is_open()。它返回一個布爾(bool)值,為真(true)代表文件已經(jīng)被順利打開,假( false )則相反。

?

#include <fstream> ofstream //文件寫操作 內(nèi)存寫入存儲設(shè)備 ifstream //文件讀操作,存儲設(shè)備讀區(qū)到內(nèi)存中 fstream //讀寫操作,對打開的文件可進行讀寫操作

在fstream類中,成員函數(shù)open()實現(xiàn)打開文件的操作,從而將數(shù)據(jù)流和文件進行關(guān)聯(lián),通過ofstream,ifstream,fstream對象 進行對文件的讀寫操作

在fstream類中,有一個成員函數(shù)open(),就是用來打開文件的,其原型是:

void open(const char* filename,int mode,int access);

參數(shù):

filename: 要打開的文件名 mode: 要打開文件的方式 access: 打開文件的屬性

打開文件的方式在類ios(是所有流式I/O類的基類)中定義,常用的值如下:

ios::app: 以追加的方式打開文件 ios::ate: 文件打開后定位到文件尾,ios:app就包含有此屬性 ios::binary: 以二進制方式打開文件,缺省的方式是文本方式。兩種方式的區(qū)別見前文 ios::in: 文件以輸入(讀)方式打開 ios::out: 文件以輸出(寫)方式打開 ios::nocreate: 不建立文件,所以文件不存在時打開失敗 ios::noreplace:不覆蓋文件,所以打開文件時如果文件存在失敗 ios::trunc: 如果文件存在,把文件長度設(shè)為0。即刪除該文件。

可以用“或”把以上屬性連接起來,如ios::out|ios::binary

ofstream out; out.open("Hello.txt", ios::in|ios::out|ios::binary) //根據(jù)自己需要進行適當(dāng)?shù)倪x取

打開文件的屬性取值是:

0:普通文件,打開訪問 1:只讀文件 2:隱含文件 4:系統(tǒng)文件

可以用“或”或者“+”把以上屬性連接起來 ,如3或1|2就是以只讀和隱含屬性打開文件。

例如:以二進制輸入方式打開文件c:config.sys

fstream file1; file1.open("c:config.sys",ios::binary|ios::in,0); // 如果open函數(shù)只有文件名一個參數(shù),則是以讀/寫普通文件打開,即: // file1.open("c:config.sys");<=>file1.open("c:config.sys",ios::in|ios::out,0); // 另外,fstream還有和open()一樣的構(gòu)造函數(shù),對于上例,在定義的時侯就可以打開文件了: fstream file1("c:config.sys"); // fstream有兩個子類:ifstream(input file stream)和ofstream(outpu file stream),ifstream默認以輸入方式打開文件,而ofstream默認以輸出方式打開文件。 ifstream file2("c:pdos.def");//以輸入方式打開文件 ofstream file3("c:x.123");//以輸出方式打開文件

所以,在實際應(yīng)用中,根據(jù)需要的不同,選擇不同的類來定義:如果想以輸入方式打開,就用ifstream來定義;如果想以輸出方式打開,就用ofstream來定義;如果想以輸入/輸出方式來打開,就用fstream來定義。很多程序中,可能會碰到ofstream out("Hello.txt"), ifstream in("..."),fstream foi("...")這樣的的使用,并沒有顯式的去調(diào)用open()函數(shù)就進行文件的操作,直接調(diào)用了其默認的打開方式,因為在stream類的構(gòu)造函數(shù)中調(diào)用了open()函數(shù),并擁有同樣的構(gòu)造函數(shù),所以在這里可以直接使用流對象進行文件的操作,默認方式如下:

ofstream out("...", ios::out); ifstream in("...", ios::in); fstream foi("...", ios::in|ios::out);

當(dāng)使用默認方式進行對文件的操作時,你可以使用成員函數(shù)is_open()對文件是否打開進行驗證

?

?

關(guān)閉文件(Closing a file)

當(dāng)文件讀寫操作完成之后,我們必須將文件關(guān)閉以使文件重新變?yōu)榭稍L問的。關(guān)閉文件需要調(diào)用成員函數(shù)close(),它負責(zé)將緩存中的數(shù)據(jù)排放出來并關(guān)閉文件。
void close (); ? ?這個函數(shù)一旦被調(diào)用,原先的流對象(stream object)就可以被用來打開其它的文件了,這個文件也就可以重新被其它的進程(process)所有訪問了。
為防止流對象被銷毀時還聯(lián)系著打開的文件,析構(gòu)函數(shù)(destructor)將會自動調(diào)用關(guān)閉函數(shù)close。

?

打開的文件使用完成后一定要關(guān)閉,fstream提供了成員函數(shù)close()來完成此操作,如:file1.close();就把file1相連的文件關(guān)閉。

?

?

讀寫文件


讀寫文件分為?文本文件?二進制文件 的讀取,

對于文本文件的讀取比較簡單,用插入器和析取器就可以。而對于二進制的讀取就要復(fù)雜些。
下要就詳細的介紹這兩種方式:

?

文本文件(Text mode files)

類ofstream, ifstream 和fstream 是分別從ostream, istream 和iostream 中引申而來的。這就是為什么 fstream 的對象可以使用其父類的成員來訪問數(shù)據(jù)。
一般來說,我們將使用這些類與同控制臺(console)交互同樣的成員函數(shù)(cin 和 cout)來進行輸入輸出。如下面的例題所示,我們使用重載的插入操作符

文本文件的讀寫很簡單:用插入器(>>)從文件輸入。假設(shè)file1是以輸入方式打開,file2以輸出打開。示例如下:

file2<<"I Love You";//向文件寫入字符串"I Love You" int i; file1>>i;//從文件輸入一個整數(shù)值。

這種方式還有一種簡單的格式化能力,比如可以指定輸出為16進制等等,具體的格式有以下一些

?

操縱符 功能 輸入/輸出
dec 格式化為十進制數(shù)值數(shù)據(jù) 輸入和輸出
endl 輸出一個換行符并刷新此流 輸出
ends 輸出一個空字符 輸出
hex 格式化為十六進制數(shù)值數(shù)據(jù) 輸入和輸出
oct 格式化為八進制數(shù)值數(shù)據(jù) 輸入和輸出
setpxecision(int p) 設(shè)置浮點數(shù)的精度位數(shù) 輸出

比如要把123當(dāng)作十六進制輸出:file1<<hex<<123;要把3.1415926以5位精度輸出:file1<<setpxecision(5)<<3.1415926。

類ofstream, ifstream 和fstream 是分別從ostream, istream 和iostream 中引申而來的。這就是為什么 fstream 的對象可以使用其父類的成員來訪問數(shù)據(jù)。
一般來說,我們將使用這些類與同控制臺(console)交互同樣的成員函數(shù)(cin 和 cout)來進行輸入輸出。如下面的例題所示,我們使用重載的插入操作符<<:

// writing on a text file #include <fiostream.h> int main () { ofstream out("out.txt"); if (out.is_open()) { out << "This is a line.\n"; out << "This is another line.\n"; out.close(); } return 0; } //結(jié)果: 在out.txt中寫入: This is a line. This is another line 從文件中讀入數(shù)據(jù)也可以用與 cin>>的使用同樣的方法: // reading a text file #include <iostream.h> #include <fstream.h> #include <stdlib.h> int main () { char buffer[256]; ifstream in("test.txt"); if (! in.is_open()) { cout << "Error opening file"; exit (1); } while (!in.eof() ) { in.getline (buffer,100); cout << buffer << endl; } return 0; } //結(jié)果 在屏幕上輸出 This is a line. This is another line

例子中讀入一個文本文件的內(nèi)容,然后將它打印到屏幕上。注意我們使用了一個新的成員函數(shù)叫做eof ,它是ifstream 從類 ios 中繼承過來的,當(dāng)?shù)竭_文件末尾時返回true 。

?

二進制文件(Binary files)

在二進制文件中,使用<< 和>>,以及函數(shù)(如getline)來操作符輸入和輸出數(shù)據(jù),沒有什么實際意義,雖然它們是符合語法的。

文件流包括兩個為順序讀寫數(shù)據(jù)特殊設(shè)計的成員函數(shù):write 和 read。第一個函數(shù) (write) 是ostream 的一個成員函數(shù),都是被ofstream所繼承。而read 是istream 的一個成員函數(shù),被ifstream 所繼承。類 fstream 的對象同時擁有這兩個函數(shù)。它們的原型是:

write ( char * buffer, streamsize size );
read ( char * buffer, streamsize size );

這里 buffer 是一塊內(nèi)存的地址,用來存儲或讀出數(shù)據(jù)。參數(shù)size 是一個整數(shù)值,表示要從緩存(buffer)中讀出或?qū)懭氲淖址麛?shù)。

// reading binary file #include <iostream> #include <fstream> using namespace std; int main () {const char * filename = "example.txt";char * buffer;long size;ifstream file(filename, ios::in|ios::binary|ios::ate);size = file.tellg();file.seekg(0, ios::beg);buffer = new char [size];file.read(buffer, size);file.close();cout <<"the complete file is in a buffer";delete[] buffer;return 0; } //The complete file is in a buffer

①put()

put()函數(shù)向流寫入一個字符,其原型是ofstream &put(char ch),使用也比較簡單,如file1.put(‘c’);就是向流寫一個字符’c’。

②get()

get()函數(shù)比較靈活,有3種常用的重載形式:

一種就是和put()對應(yīng)的形式:ifstream &get(char &ch);功能是從流中讀取一個字符,結(jié)果保存在引用ch中,如果到文件尾,返回空字符。如file2.get(x);表示從文件中讀取一個字符,并把讀取的字符保存在x中。

另一種重載形式的原型是: int get();這種形式是從流中返回一個字符,如果到達文件尾,返回EOF,如x=file2.get();和上例功能是一樣的。

還 有一種形式的原型是:ifstream &get(char *buf,int num,char delim=’n’);這種形式把字符讀入由 buf 指向的數(shù)組,直到讀入了 num 個字符或遇到了由 delim 指定的字符,如果沒使用 delim 這個參數(shù),將使用缺省值換行符’n’。例如:

file2.get(str1,127,’A’);//從文件中讀取字符到字符串str1,當(dāng)遇到字符’A’或讀取了127個字符時終止。

③讀寫數(shù)據(jù)塊

要讀寫二進制數(shù)據(jù)塊,使用成員函數(shù)read()和write()成員函數(shù),它們原型如下:

read(unsigned char *buf,int num);
write(const unsigned char *buf,int num);
read() 從文件中讀取 num 個字符到 buf 指向的緩存中,如果在還未讀入 num 個字符時就到了文件尾,可以用成員函數(shù) int gcount();來取得實際讀取的字符數(shù);而 write() 從buf 指向的緩存寫 num 個字符到文件中,值得注意的是緩存的類型是 unsigned char *,有時可能需要類型轉(zhuǎn)換。

unsigned char str1[]="I Love You"; int n[5]; ifstream in("xxx.xxx"); ofstream out("yyy.yyy"); out.write(str1,strlen(str1));//把字符串str1全部寫到y(tǒng)yy.yyy中 in.read((unsigned char*)n,sizeof(n));//從xxx.xxx中讀取指定個整數(shù),注意類型轉(zhuǎn)換 in.close();out.close();

?

?

狀態(tài)標(biāo)志符的驗證(Verification of state flags)

除了eof()以外,還有一些驗證流的狀態(tài)的成員函數(shù)(所有都返回bool型返回值):

bad():如果在讀寫過程中出錯,返回 true 。例如:當(dāng)我們要對一個不是打開為寫狀態(tài)的文件進行寫入時,或者我們要寫入的設(shè)備沒有剩余空間的時候。
fail():除了與bad() 同樣的情況下會返回 true 以外,加上格式錯誤時也返回true ,例如當(dāng)想要讀入一個整數(shù),而獲得了一個字母的時候。
eof():如果讀文件到達文件末尾,返回true。
good():這是最通用的:如果調(diào)用以上任何一個函數(shù)返回true 的話,此函數(shù)返回 false 。

要想重置以上成員函數(shù)所檢查的狀態(tài)標(biāo)志,你可以使用成員函數(shù)clear(),沒有參數(shù)。

?

緩存和同步(Buffers and Synchronization)

當(dāng)我們對文件流進行操作的時候,它們與一個streambuf 類型的緩存(buffer)聯(lián)系在一起。這個緩存(buffer)實際是一塊內(nèi)存空間,作為流(stream)和物理文件的媒介。例如,對于一個輸出流, 每次成員函數(shù)put (寫一個單個字符)被調(diào)用,這個字符不是直接被寫入該輸出流所對應(yīng)的物理文件中的,而是首先被插入到該流的緩存(buffer)中。

當(dāng)緩存被排放出來(flush)時,它里面的所有數(shù)據(jù)或者被寫入物理媒質(zhì)中(如果是一個輸出流的話),或者簡單的被抹掉(如果是一個輸入流的話)。這個過程稱為同步(synchronization),它會在以下任一情況下發(fā)生:

?

1. 當(dāng)文件被關(guān)閉時: 在文件被關(guān)閉之前,所有還沒有被完全寫出或讀取的緩存都將被同步。
2. 當(dāng)緩存buffer 滿時:緩存Buffers 有一定的空間限制。當(dāng)緩存滿時,它會被自動同步。
3. 控制符明確指明:當(dāng)遇到流中某些特定的控制符時,同步會發(fā)生。這些控制符包括:flush 和endl。
4. 明確調(diào)用函數(shù)sync(): 調(diào)用成員函數(shù)sync() (無參數(shù))可以引發(fā)立即同步。這個函數(shù)返回一個int 值,等于-1 表示流沒有聯(lián)系的緩存或操作失敗

?

檢測 EOF

成員函數(shù)eof()用來檢測是否到達文件尾,如果到達文件尾返回非0值,否則返回0。原型是int eof();

if(in.eof())ShowMessage("已經(jīng)到達文件尾!");

?

文件定位

和 C的文件操作方式不同的是,C++ I/O系統(tǒng)管理兩個與一個文件相聯(lián)系的指針。一個是讀指針,它說明輸入操作在文件中的位置;另一個是寫指針,它下次寫操作的位置。每次執(zhí)行輸入或輸出時, 相應(yīng)的指針自動變化。所以,C++的文件定位分為讀位置和寫位置的定位,對應(yīng)的成員函數(shù)是 seekg()和 seekp(),seekg()是設(shè)置讀位置,seekp是設(shè)置寫位置。它們最通用的形式如下:

istream &seekg(streamoff offset,seek_dir origin); ostream &seekp(streamoff offset,seek_dir origin);

streamoff 定義于 iostream.h 中,定義有偏移量 offset 所能取得的最大值,seek_dir 表示移動的基準(zhǔn)位置,是一個有以下值的枚舉:

ios::beg: 文件開頭 ios::cur: 文件當(dāng)前位置 ios::end: 文件結(jié)尾

這兩個函數(shù)一般用于二進制文件,因為文本文件會因為系統(tǒng)對字符的解釋而可能與預(yù)想的值不同。

file1.seekg(1234,ios::cur);//把文件的讀指針從當(dāng)前位置向后移1234個字節(jié) file2.seekp(1234,ios::beg);//把文件的寫指針從文件開頭向后移1234個字節(jié)

?

?

獲得和設(shè)置流指針(get and put stream pointers)

所有輸入/輸出流對象(i/o streams objects)都有至少一個流指針:

ifstream, 類似istream, 有一個被稱為get pointer的指針,指向下一個將被讀取的元素。
ofstream, 類似 ostream, 有一個指針 put pointer ,指向?qū)懭胂乱粋€元素的位置。
fstream, 類似 iostream, 同時繼承了get 和 put
我們可以通過使用以下成員函數(shù)來讀出或配置這些指向流中讀寫位置的流指針:

tellg() 和 tellp()

這兩個成員函數(shù)不用傳入?yún)?shù),返回pos_type 類型的值(根據(jù)ANSI-C++ 標(biāo)準(zhǔn)) ,就是一個整數(shù),代表當(dāng)前get 流指針的位置 (用tellg) 或 put 流指針的位置(用tellp).
seekg() 和seekp()

這對函數(shù)分別用來改變流指針get 和put的位置。兩個函數(shù)都被重載為兩種不同的原型:

seekg ( pos_type position ); seekp ( pos_type position );

使用這個原型,流指針被改變?yōu)橹赶驈奈募_始計算的一個絕對位置。要求傳入的參數(shù)類型與函數(shù) tellg 和tellp 的返回值類型相同。

seekg ( off_type offset, seekdir direction ); seekp ( off_type offset, seekdir direction );

使用這個原型可以指定由參數(shù)direction決定的一個具體的指針開始計算的一個位移(offset)。它可以是:

ios::beg 從流開始位置計算的位移 ios::cur 從流指針當(dāng)前位置開始計算的位移 ios::end 從流末尾處開始計算的位移

?

流指針 get 和 put 的值對文本文件(text file)和二進制文件(binary file)的計算方法都是不同的,因為文本模式的文件中某些特殊字符可能被修改。由于這個原因,建議對以文本文件模式打開的文件總是使用seekg 和 seekp的第一種原型,而且不要對tellg 或 tellp 的返回值進行修改。對二進制文件,你可以任意使用這些函數(shù),應(yīng)該不會有任何意外的行為產(chǎn)生。

以下例子使用這些函數(shù)來獲得一個二進制文件的大小:

// obtaining file size #include <iostream> #include <fstream> using namespace std;int main () {const char * filename = "example.txt";long l,m;ifstream file(filename, ios::in|ios::binary);l = file.tellg();file.seekg(0, ios::end);m = file.tellg();file.close();cout <<"size of "<< filename;cout <<" is "<< (m-l)<<" bytes.\n";return 0; } //size of example.txt is 40 bytes.

?

?

C語言文件操作詳解

?

基于C的文件操作

在ANSI C中,對文件的操作分為兩種方式,即流式文件操作和I/O文件操作,下面就分別介紹之。

一、流式文件操作:這種方式的文件操作有一個重要的結(jié)構(gòu)FILE,FILE在stdio.h中定義如下:

typedef struct {short level; /* fill/empty level of buffer */unsigned flags; /* File status flags */char fd; /* File descriptor */unsigned char hold; /* Ungetc char if no buffer */short bsize; /* Buffer size */unsigned char *buffer; /* Data transfer buffer */unsigned char *curp; /* Current active pointer */unsigned istemp; /* Temporary file indicator */short token; /* Used for validity checking */ }FILE; /* This is the FILE object */ FILE這個結(jié)構(gòu)包含了文件操作的基本屬性,對文件的操作都要通過這個結(jié)構(gòu)的指針來進行。

C語言中沒有輸入輸出語句,所有的輸入輸出功能都用 ANSI C提供的一組標(biāo)準(zhǔn)庫函數(shù)來實現(xiàn)。文件操作標(biāo)準(zhǔn)庫函數(shù)有:

      文件的打開操作 fopen 打開一個文件文件的關(guān)閉操作 fclose 關(guān)閉一個文件文件的讀寫操作 fgetc 從文件中讀取一個字符fputc 寫一個字符到文件中去fgets 從文件中讀取一個字符串fputs 寫一個字符串到文件中去fprintf 往文件中寫格式化數(shù)據(jù)fscanf 格式化讀取文件中數(shù)據(jù)fread 以二進制形式讀取文件中的數(shù)據(jù)fwrite 以二進制形式寫數(shù)據(jù)到文件中去getw 以二進制形式讀取一個整數(shù)putw 以二進制形式存貯一個整數(shù)文件狀態(tài)檢查函數(shù) feof 文件結(jié)束ferror 文件讀/寫出錯clearerr 清除文件錯誤標(biāo)志ftell 了解文件指針的當(dāng)前位置文件定位函數(shù) rewind 反繞fseek 隨機定位

?

?

?

文件的打開

 1.函數(shù)原型:FILE *fopen(char *pname,char *mode)

 2.功能說明
   按照mode 規(guī)定的方式,打開由pname指定的文件。若找不到由pname指定的相應(yīng)文件,就按以下方式之一處理:
? ? ? ?(1) 此時如mode 規(guī)定按寫方式打開文件,就按由pname指定的名字建立一個新文件;
? ? ? ?(2) 此時如mode 規(guī)定按讀方式打開文件,就會產(chǎn)生一個錯誤。

? ? ? ? 打開文件的作用是:
? ? ? ? (1)分配給打開文件一個FILE 類型的文件結(jié)構(gòu)體變量,并將有關(guān)信息填入文件結(jié)構(gòu)體變量;
? ? ? ? (2)開辟一個緩沖區(qū);
? ? ? ? (3)調(diào)用操作系統(tǒng)提供的打開文件或建立新文件功能,打開或建立指定文件;
? ? ? ? FILE *:指出fopen是一個返回文件類型的指針函數(shù);

 3.參數(shù)說明

pname:是一個字符指針,指向要打開的文件名。 mode:是一個指向文件處理方式字符串的字符指針。 字符串 含義 "r" 打開只讀文件,該文件必須存在。 "w" 打開只寫文件,若文件存在則文件長度清為0,即該文件內(nèi)容會消失。若文件不存在則建立該文件。 "a" 以追加方式打開只寫文件。文件不存在建立該文件,如文件存在,寫入的數(shù)據(jù)會被加到文件尾,即文件原先的內(nèi)容會被保留。 "r+" 以讀/寫方式打開文件,該文件必須存在。如無文件則出錯 "w+" 以讀/寫方式打開文件,若文件存在則文件長度清為零,即文件內(nèi)容清空。若文件不存在則建立該文件。

上述的形態(tài)字符串都可以再加一個b字符,如rb、w+b或ab+等組合,加入b 字符用來告訴函數(shù)庫打開的文件為二進制文件,而非純文字文件。不過在POSIX系統(tǒng),包含Linux都會忽略該字符。由fopen()所建立的新文件會具有S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH(0666)權(quán)限,此文件權(quán)限也會參考umask值。
返回值 文件順利打開后,指向該流的文件指針就會被返回。若果文件打開失敗則返回NULL,并把錯誤代碼存在errno 中。
附加說明 一般而言,開文件后會作一些文件讀取或?qū)懭氲膭幼?#xff0c;若開文件失敗,接下來的讀寫動作也無法順利進行,所以在fopen()后請作錯誤判斷及處理。

  一個文件可以以文本模式或二進制模式打開,這兩種的區(qū)別是:在文本模式中回車被當(dāng)成一個字符''\n'',而二進制模式認為它是兩個字符0x0D,0x0A;如果在文件中讀到0x1B,文本模式會認為這是文件結(jié)束符,也就是二進制模型不會對文件進行處理,而文本方式會按一定的方式對數(shù)據(jù)作相應(yīng)的轉(zhuǎn)換。

  系統(tǒng)默認的是以文本模式打開,可以修改全部變量_fmode的值來修改這個設(shè)置,例如_fmode=O_TEXT;就設(shè)置默認打開方式為文本模式;而_fmode=O_BINARY;則設(shè)置默認打開方式是二進制模式。
  我們也可以在模式字符串中指定打開的模式,如"rb"表示以二進制模式打開只讀文件,"w+t"或"wt+"表示以文本模式打開讀/寫文件。
  此函數(shù)返回一個FILE指針,所以申明一個FILE指針后不用初始化,而是用fopen()來返回一個指針并與一個特定的文件相連,如果成敗,返回NULL。

?

 4.返回值
   正常返回:被打開文件的文件指針。
   異常返回:NULL,表示打開操作不成功。

//定義一個名叫fp文件指針 FILE *fp; //判斷按讀方式打開一個名叫test的文件是否失敗 if((fp=fopen("test","r")) == NULL)//打開操作不成功 {printf("The file can not be opened.\n");  exit(1);//結(jié)束程序的執(zhí)行 } FILE *fp; if(fp=fopen("123.456","wb"))puts("打開文件成功"); elseputs("打開文件成敗");

要說明的是:C語言將計算機的輸入輸出設(shè)備都看作是文件。例如,鍵盤文件、屏幕文件等。ANSI C標(biāo)準(zhǔn)規(guī)定,在執(zhí)行程序時系統(tǒng)先自動打開鍵盤、屏幕、錯誤三個文件。這三個文件的文件指針分別是:標(biāo)準(zhǔn)輸入stdin、標(biāo)準(zhǔn)輸出stdout和標(biāo)準(zhǔn)出錯 stderr。

freopen(打開文件)

相關(guān)函數(shù) fopen,fclose
表頭文件 #include<stdio.h>
定義函數(shù) FILE * freopen(const char * path,const char * mode,FILE * stream);
函數(shù)說明 參數(shù)path字符串包含欲打開的文件路徑及文件名,參數(shù)mode請參考fopen()說明。參數(shù)stream為已打開的文件指針。Freopen()會將原stream所打開的文件流關(guān)閉,然后打開參數(shù)path的文件。
返回值 文件順利打開后,指向該流的文件指針就會被返回。如果文件打開失敗則返回NULL,并把錯誤代碼存在errno 中。

#include<stdio.h> main() { FILE * fp; fp=fopen(“/etc/passwd”,”r”); fp=freopen(“/etc/group”,”r”,fp); fclose(fp); }

?

?

文件的關(guān)閉

1. 函數(shù)原型:int fclose(FILE *fp);

2. 功能說明
  關(guān)閉由fp指出的文件。此時調(diào)用操作系統(tǒng)提供的文件關(guān)閉功能,關(guān)閉由fp->fd指出的文件;釋放由fp指出的文件類型結(jié)構(gòu)體變量;返回操作結(jié)果,即0或EOF。

3. 參數(shù)說明
  fp:一個已打開文件的文件指針。

4. 返回值
  正常返回:0。
  異常返回:EOF,表示文件在關(guān)閉時發(fā)生錯誤。
例如:

int n=fclose(fp);

?

文件的讀寫操作

1. 從文件中讀取一個字符

  1. 函數(shù)原型:int fgetc(FILE *fp);

  2. 功能說明:從fp所指文件中讀取一個字符。   

  3. 參數(shù)說明:fp:這是個文件指針,它指出要從中讀取字符的文件。   

  4. 返回值
    正常返回: 返回讀取字符的代碼。
    非正常返回:返回EOF。例如,要從"寫打開"文件中讀取一個字符時,會發(fā)生錯誤而返回一個EOF。

//顯示指定文件的內(nèi)容。//程序名為:display.c //執(zhí)行時可用:display filename1 形式的命令行運行。顯示文件filename1中的內(nèi)容。例如,執(zhí)行命令行display display.c將在屏幕上顯示display的原代碼。//File display program. #include <stdio.h> void main(int argc,char *argv[]) //命令行參數(shù) {int ch;//定義文件類型指針FILE *fp;//判斷命令行是否正確if(argc!=2){printf("Error format,Usage: display filename1\n");return; //鍵入了錯誤的命令行,結(jié)束程序的執(zhí)行}//按讀方式打開由argv[1]指出的文件if((fp=fopen(argv[1],"r"))==NULL){printf("The file <%s> can not be opened.\n",argv[1]);//打開操作不成功return;//結(jié)束程序的執(zhí)行}//成功打開了argv[1]所指文件ch=fgetc(fp); //從fp所指文件的當(dāng)前指針位置讀取一個字符while(ch!=EOF) //判斷剛讀取的字符是否是文件結(jié)束符{putchar(ch); //若不是結(jié)束符,將它輸出到屏幕上顯示ch=fgetc(fp); //繼續(xù)從fp所指文件中讀取下一個字符} //完成將fp所指文件的內(nèi)容輸出到屏幕上顯示fclose(fp); //關(guān)閉fp所指文件 }

?

2. 寫一個字符到文件中去

1. 函數(shù)原型:int fputc(int ch,FILE *fp)

2. 功能說明:把ch中的字符寫入由fp指出的文件中去。 

3. 參數(shù)說明
  ch:是一個整型變量,內(nèi)存要寫到文件中的字符(C語言中整型量和字符量可以通用)。
  fp:這是個文件指針,指出要在其中寫入字符的文件。

4. 返回值
  正常返回: 要寫入字符的代碼。
  非正常返回:返回EOF。例如,要往"讀打開"文件中寫一個字符時,會發(fā)生錯誤而返回一個EOF。

//將一個文件的內(nèi)容復(fù)制到另一個文件中去。//程序名為:copyfile.c //執(zhí)行時可用:copyfile filename1 filename2形式的命令行運行,將文件filename1中的內(nèi)容復(fù)制到文件filename2中去。 //file copy program. #include <stdio.h> void main(int argc,char *argv[]) //命令行參數(shù) {int ch;FILE *in,*out; //定義in和out兩個文件類型指針if(argc!=3) //判斷命令行是否正確{printf("Error in format,Usage: copyfile filename1 filename2\n");return; //命令行錯,結(jié)束程序的執(zhí)行}//按讀方式打開由argv[1]指出的文件if((in=fopen(argv[1],"r"))==NULL){printf("The file <%s> can not be opened.\n",argv[1]);return; //打開失敗,結(jié)束程序的執(zhí)行}//成功打開了argv[1]所指文件,再//按寫方式打開由argv[2]指出的文件if((out=fopen(argv[2],"w"))==NULL){printf("The file %s can not be opened.\n",argv[2]);return; //打開失敗,結(jié)束程序的執(zhí)行}//成功打開了argv[2]所指文件ch=fgetc(in); //從in所指文件的當(dāng)前指針位置讀取一個字符while(ch!=EOF) //判斷剛讀取的字符是否是文件結(jié)束符{fputc(ch,out); //若不是結(jié)束符,將它寫入out所指文件ch=fgetc(in); //繼續(xù)從in所指文件中讀取下一個字符} //完成將in所指文件的內(nèi)容寫入(復(fù)制)到out所指文件中fclose(in); //關(guān)閉in所指文件fclose(out); //關(guān)閉out所指文件 }

示例代碼

//按十進制和字符顯示文件代碼,若遇不可示字符就用井號"#"字符代替之。 //程序名為:dumpf.c //執(zhí)行時可用:dumpf filename1 形式的命令行運行。 // File dump program. #include <stdio.h> void main(int argc,char *argv[]) {char str[9];int ch,count,i;FILE *fp;if(argc!=2){printf("Error format,Usage: dumpf filename\n");return;}if((fp=fopen(argv[1],"r"))==NULL){printf("The file %s can not be opened.\n",argv[1]);return;}count=0;do{i=0;//按八進制輸出第一列,作為一行八個字節(jié)的首地址printf("%06o: ",count*8);do{// 從打開的文件中讀取一個字符ch=fgetc(fp);// 按十進制方式輸出這個字符的ASCII碼printf("%4d",ch);// 如果是不可示字符就用"#"字符代替if(ch<' '||ch>'~') str[i]='#';// 如果是可示字符,就將它存入數(shù)組str以便形成字符串else str[i]=ch;// 保證每一行輸出八個字符if(++i==8) break;}while(ch!=EOF); // 遇到文件尾標(biāo)志,結(jié)束讀文件操作str[i]='\0'; // 在數(shù)組str加字符串結(jié)束標(biāo)志for(;i<8;i++) printf(" "); // 一行不足八個字符用空格填充printf(" %s\n",str); // 輸出字符串count++; // 準(zhǔn)備輸出下一行}while(ch!=EOF); // 直到文件結(jié)束fclose(fp); // 關(guān)閉fp所指文件 }

?

3. 從文件中讀取一個字符串

1. 函數(shù)原型:char *fgets(char *str,int n,FILE *fp)
2. 功能說明
  從由fp指出的文件中讀取n-1個字符,并把它們存放到由str指出的字符數(shù)組中去,最后加上一個字符串結(jié)束符'\0'。
3. 參數(shù)說明
  str:接收字符串的內(nèi)存地址,可以是數(shù)組名,也可以是指針。
  n: 指出要讀取字符的個數(shù)。
  fp:這是個文件指針,指出要從中讀取字符的文件。
4. 返回值

正常返回:返回字符串的內(nèi)存首地址,即str的值。
非正常返回:返回一個NULL值,此時應(yīng)當(dāng)用feof()或ferror()函數(shù)來判別是讀取到了文件尾,還是發(fā)生了錯誤。例如,要從"寫打開"文件中讀取字符串,將
發(fā)生錯誤而返回一個NULL值。

?

4. 寫一個字符串到文件中去

1. 函數(shù)原型:int fputs(char *str,FILE *fp)

2. 功能說明
  把由str指出的字符串寫入到fp所指的文件中去。
3. 參數(shù)說明
  str:指出要寫到文件中去的字符串。
  fp:這是個文件指針,指出字符串要寫入其中的文件。
4. 返回值
  正常返回: 寫入文件的字符個數(shù),即字符串的長度。
  非正常返回:返回一個NULL值,此時應(yīng)當(dāng)用feof()或ferror()函數(shù)來判別是讀取到了文件尾,還是發(fā)生了錯誤。例如,要往一個"讀打開" 文件中寫字符串時,
會發(fā)生錯誤而返回一個NULL值。

//以下程序?qū)⒁粋€文件的內(nèi)容附加到另一個文件中去。 //程序名:linkfile.c //執(zhí)行時可用:linkfile filename1 filename2形式的命令行運行,將文件filename2的內(nèi)容附加在文件filename1之后。 // file linked program. #include <stdio.h> #define SIZE 512 void main(int argc,char *argv[]) {char buffer[SIZE];FILE *fp1,*fp2;if(argc!=3){printf("Usage: linkfile filename1 filename2\n");return;}// 按追加方式打開argv[1] 所指文件if((fp1=fopen(argv[1],"a"))==NULL){printf("The file %s can not be opened.\n",argv[1]);return;}if((fp2=fopen(argv[2],"r"))==NULL){printf("The file %s can not be opened.\n",argv[2]);return;}// 讀入一行立即寫出,直到文件結(jié)束while(fgets(buffer,SIZE,fp1)!=NULL)printf("%s\n",buffer);while(fgets(buffer,SIZE,fp2)!=NULL)fputs(buffer,fp1);fclose(fp1);fclose(fp2);if((fp1=fopen(argv[1],"r"))==NULL){printf("The file %s can not be opened.\n",argv[1]);return;}while(fgets(buffer,SIZE,fp1)!=NULL)printf("%s\n",buffer);fclose(fp1); }

?

5. 往文件中寫格式化數(shù)據(jù)

1.函數(shù)原型:int fprintf(FILE *fp,char *format,arg_list)

2.功能說明
  將變量表列(arg_list)中的數(shù)據(jù),按照format指出的格式,寫入由fp指定的文件。fprintf()函數(shù)與printf()函數(shù)的功能相同,只是printf()函數(shù)是將數(shù)據(jù)寫入屏幕文件(stdout)。
3.參數(shù)說明
  fp:這是個文件指針,指出要將數(shù)據(jù)寫入的文件。
  format:這是個指向字符串的字符指針,字符串中含有要寫出數(shù)據(jù)的格式,所以該字符串成為格式串。格式串描述的規(guī)則與printf()函數(shù)中的格式串相同。
arg_list:是要寫入文件的變量表列,各變量之間用逗號分隔。
4.返回值:無。

// 下列程序的執(zhí)行文件為display.exe,執(zhí)行時鍵入命令行: //   display [-i][-s] filename // 下面的表格列出了命令行參數(shù)的含義及其功能://存儲文件名:save.txt //程序代碼如下: // file display program. #include <stdio.h> void main() {char name[10];int nAge,nClass;long number;FILE *fp;if((fp=fopen("student.txt","w"))==NULL){printf("The file %s can not be opened.\n","student.txt");return;}fscanf(stdin,"%s %d %d %ld",name,&nClass,&nAge,&number);fprintf(fp,"%s %5d %4d %8ld",name,nClass,nAge,number);fclose(fp);if((fp=fopen("student.txt","r"))==NULL){printf("The file %s can not be opened.\n","student.txt");return;}fscanf(fp,"%s %d %d %ld",name,&nClass,&nAge,&number);printf("name nClass nAge number\n");fprintf(stdout,"%-10s%-8d%-6d%-8ld\n",name,nClass,nAge,number);fclose(fp); }

?

fscanf ?從一個流中執(zhí)行格式化輸入
表頭文件:#include<stdio.h>
函數(shù)原型:int fscanf(FILE *stream, char *format[,argument...]);
FILE* 一個FILE型的指針
char* 格式化輸出函數(shù),和scanf里的格式一樣
返回值:成功時返回轉(zhuǎn)換的字節(jié)數(shù),失敗時返回一個負數(shù)
fp = fopen("/local/test.c","a+");
fscanf(fp,"%s",str);

?

fdopen(將文件描述詞轉(zhuǎn)為文件指針)
相關(guān)函數(shù) fopen,open,fclose
表頭文件 #include<stdio.h>
定義函數(shù) FILE * fdopen(int fildes,const char * mode);
函數(shù)說明 fdopen()會將參數(shù)fildes 的文件描述詞,轉(zhuǎn)換為對應(yīng)的文件指針后返回。參數(shù)mode 字符串則代表著文件指針的流形態(tài),此形態(tài)必須和原先文件描述詞讀寫模式相同。關(guān)于mode 字符串格式請參考fopen()。
返回值 轉(zhuǎn)換成功時返回指向該流的文件指針。失敗則返回NULL,并把錯誤代碼存在errno中。

#include<stdio.h> main() { FILE * fp =fdopen(0,”w+”); fprintf(fp,”%s/n”,”hello!”); fclose(fp); } 執(zhí)行 hello!

?

fflush(更新緩沖區(qū))
相關(guān)函數(shù) write,fopen,fclose,setbuf
表頭文件 #include<stdio.h>
定義函數(shù) int fflush(FILE* stream);
函數(shù)說明 fflush()會強迫將緩沖區(qū)內(nèi)的數(shù)據(jù)寫回參數(shù)stream指定的文件中。如果參數(shù)stream為NULL,fflush()會將所有打開的文件數(shù)據(jù)更新。
返回值 成功返回0,失敗返回EOF,錯誤代碼存于errno中。
錯誤代碼 EBADF 參數(shù)stream 指定的文件未被打開,或打開狀態(tài)為只讀。其它錯誤代碼參考write()。

?

fileno(返回文件流所使用的文件描述詞)
相關(guān)函數(shù) open,fopen
表頭文件 #include<stdio.h>
定義函數(shù) int fileno(FILE * stream);
函數(shù)說明 fileno()用來取得參數(shù)stream指定的文件流所使用的文件描述詞。
返回值 返回文件描述詞。

#include<stdio.h> main() { FILE * fp; int fd; fp=fopen(“/etc/passwd”,”r”); fd=fileno(fp); printf(“fd=%d/n”,fd); fclose(fp); } 執(zhí)行 fd=3

?

6. 以二進制形式讀取文件中的數(shù)據(jù)

1. 函數(shù)原型:int fread(void *buffer,unsigned sife,unsigned count,FILE *fp)

2. 功能說明
  從由fp指定的文件中,按二進制形式將sife*count個數(shù)據(jù)讀到由buffer指出的數(shù)據(jù)區(qū)中。
3. 參數(shù)說明

buffer:這是一個void型指針,指出要將讀入數(shù)據(jù)存放在其中的存儲區(qū)首地址。 sife:指出一個數(shù)據(jù)塊的字節(jié)數(shù),即一個數(shù)據(jù)塊的大小尺寸。 count:指出一次讀入多少個數(shù)據(jù)塊(sife)。 fp:這是個文件指針,指出要從其中讀出數(shù)據(jù)的文件。

4.返回值

  正常返回:實際讀取數(shù)據(jù)塊的個數(shù),即count。

  異常返回:如果文件中剩下的數(shù)據(jù)塊個數(shù)少于參數(shù)中count指出的個數(shù),或者發(fā)生了錯誤,返回0值。此時可以用feof()和ferror()來判定到底出現(xiàn)了什么情況。

#include<stdio.h> #define nmemb 3 struct test {char name[20];int size; }s[nmemb]; int main() {FILE * stream;int i;stream = fopen(“/tmp/fwrite”,”r”);fread(s,sizeof(struct test),nmemb,stream);fclose(stream);for(i=0;i<nmemb;i++)printf("name[%d]=%-20s:size[%d]=%d/n",i,s.name,i,s.size);return 0; }執(zhí)行結(jié)果: name[0]=Linux! size[0]=6 name[1]=FreeBSD! size[1]=8 name[2]=Windows2000 size[2]=11

?

7. 以二進制形式寫數(shù)據(jù)到文件中去

1. 函數(shù)原型:int fwrite(void *buffer,unsigned sife,unsigned count,FILE *fp)
2. 功能說明
  按二進制形式,將由buffer指定的數(shù)據(jù)緩沖區(qū)內(nèi)的sife*count個數(shù)據(jù)寫入由fp指定的文件中去。
3. 參數(shù)說明

buffer:這是一個void型指針,指出要將其中數(shù)據(jù)輸出到文件的緩沖區(qū)首地址。 sife:指出一個數(shù)據(jù)塊的字節(jié)數(shù),即一個數(shù)據(jù)塊的大小尺寸。 count:一次輸出多少個數(shù)據(jù)塊(sife)。 fp:這是個文件指針,指出要從其中讀出數(shù)據(jù)的文件。

4.返回值

  正常返回:實際輸出數(shù)據(jù)塊的個數(shù),即count。

  異常返回:返回0值,表示輸出結(jié)束或發(fā)生了錯誤。

#include <stdio.h> #define SIZE 4 struct worker { int number;char name[20];int age; }; void main() {struct worker wk;int n;FILE *in,*out;if((in=fopen("file1.txt","rb"))==NULL){printf("The file %s can not be opened.\n","file1.txt");return;}if((out=fopen("file2.txt","wb"))==NULL){printf("The file %s can not be opened.\n","file2.txt");return;}while(fread(&wk,sizeof(struct worker),1,in)==1)fwrite(&wk,sizeof(struct worker),1,out);fclose(in);fclose(out); }

示例代碼:

#include <stdio.h> #include <stdlib.h> #include <string.h> #define set_s(x,y) {strcpy(s[x].name,y);s[x].size=strlen(y);} #define nmemb 3 struct test {char name[20];int size; }s[nmemb];main() {FILE * stream;set_s(0,"Linux!");set_s(1,"FreeBSD!");set_s(2,"Windows2000.");stream=fopen("fwrite","w");fwrite(s,sizeof(struct test),nmemb,stream);fclose(stream); }執(zhí)行 參考fread()。

?

8. 以二進制形式讀取一個整數(shù)

1. 函數(shù)原型:int getw(FILE *fp)

2. 功能說明
  從由fp指定的文件中,以二進制形式讀取一個整數(shù)。
3. 參數(shù)說明
  fp:是文件指針。
4. 返回值
  正常返回:所讀取整數(shù)的值。
  異常返回:返回EOF,即-1。由于讀取的整數(shù)值有可能是-1,所以必須用feof()或ferror()來判斷是到了文件結(jié)束,還是出現(xiàn)了一個出錯。

#include <stdio.h> void main(int argc,char *argv[]) {int i,sum=0;FILE *fp;if(argc!=2){printf("Command error,Usage: readfile filename\n");exit(1);}if(!(fp=fopen(argv[1],"rb"))){printf("The file %s can not be opened.\n",argv[1]);exit(1);}for(i=1;i<=10;i++) sum+=getw(fp);printf("The sum is %d\n",sum);fclose(fp); }

?

9. 以二進制形式存貯一個整數(shù)

1.函數(shù)原型:int putw(int n,FILE *fp)

2. 功能說明
 以二進制形式把由變量n指出的整數(shù)值存放到由fp指定的文件中。
3. 參數(shù)說明
 n:要存入文件的整數(shù)。
 fp:是文件指針。
4. 返回值
 正常返回:所輸出的整數(shù)值。
 異常返回:返回EOF,即-1。由于輸出的整數(shù)值有可能是-1,所以必須用feof()或ferror()來判斷是到了文件結(jié)束,還是出現(xiàn)了一個出錯。

#include <stdio.h> void main(int argc,char *argv[]) {int i;FILE *fp;if(argc!=2){printf("Command error,Usage: writefile filename\n");return;}if(!(fp=fopen(argv[1],"wb"))){printf("The file %s can not be opened.\n",argv[1]);return;}for(i=1;i<=10;i++) printf("%d\n", putw(i,fp));fclose(fp); }

?

文件狀態(tài)檢查

1. 文件結(jié)束

(1) 函數(shù)原型:int feof(FILE *fp)

(2) 功能說明
   該函數(shù)用來判斷文件是否結(jié)束。
(3) 參數(shù)說明
   fp:文件指針。
(4) 返回值
   0:假值,表示文件未結(jié)束。
   1:真值,表示文件結(jié)束。

#include <stdio.h> void main(int argc,char *argv[]) {FILE *in,*out;char ch;if(argc!=3){printf("Usage: copyfile filename1 filename2\n");return;}if((in=fopen(argv[1],"rb"))==NULL){printf("The file %s can not be opened.\n",argv[1]);return;}if((out=fopen(argv[2],"wb"))==NULL){printf("The file %s can not be opened.\n",argv[2]);return;}while(!feof(in)){ch=fgetc(in);if(ferror(in)){printf("read error!\n");clearerr(in);}else{fputc(ch,out);if(ferror(out)){printf("write error!\n");clearerr(out);}}}fclose(in);fclose(out); }

?

2. 文件讀/寫出錯

(1) 函數(shù)原型:int ferror(FILE *fp)

(2) 功能說明
   檢查由fp指定的文件在讀寫時是否出錯。
(3) 參數(shù)說明
   fp:文件指針。
(4) 返回值
   0:假值,表示無錯誤。
   1:真值,表示出錯。

?

3. 清除文件錯誤標(biāo)志

(1) 函數(shù)原型:void clearerr(FILE *fp)

(2) 功能說明
   清除由fp指定文件的錯誤標(biāo)志。
(3) 參數(shù)說明
   fp:文件指針。
(4) 返回值:無。

#include <stdio.h> void main(int argc,char *argv[]) {FILE *in,*out;char ch;if(argc!=3){printf("Usage: copyfile filename1 filename2\n");return;}if((in=fopen(argv[1],"rb"))==NULL){printf("The file %s can not be opened.\n",argv[1]);return;}if((out=fopen(argv[2],"wb"))==NULL){printf("The file %s can not be opened.\n",argv[2]);return;}while(!feof(in)){ch=fgetc(in);if(ferror(in)){printf("read error!\n");clearerr(in);}else{fputc(ch,out);if(ferror(out)){printf("write error!\n");clearerr(out);}}}fclose(in);fclose(out); }

?

4. 了解文件指針的當(dāng)前位置

(1) 函數(shù)原型:long ftell(FILE *fp)

(2) 功能說明
   取得由fp指定文件的當(dāng)前讀/寫位置,該位置值用相對于文件開頭的位移量來表示。
(3) 參數(shù)說明
   fp:文件指針。
(4) 返回值
   正常返回:位移量(這是個長整數(shù))。
   異常返回:-1,表示出錯。
(5) 實例

?

文件定位

1. 反繞

(1) 函數(shù)原型:void rewind(FILE *fp)

(2) 功能說明
   使由文件指針fp指定的文件的位置指針重新指向文件的開頭位置。
(3) 參數(shù)說明
   fp:文件指針。
(4) 返回值:無。

#include <stdio.h> void main() {FILE *in,*out;in=fopen("filename1","r");out=fopen("filename2","w");while(!feof(in)) fputc(fgetc(in),out);rewind(out);while(!feof(in)) putchar(fgetc(in));fclose(in);fclose(out); }

?

2. 隨機定位:移動文件流的讀寫位置

(1) 函數(shù)原型:int fseek(FILE *fp,long offset,int base)

(2) 功能說明
   使文件指針fp移到基于base的相對位置offset處。
(3)參數(shù)說明
   fp:文件指針。
   offset:相對base的字節(jié)位移量。這是個長整數(shù),用以支持大于64KB的文件。
   base:文件位置指針移動的基準(zhǔn)位置,是計算文件位置指針位移的基點。ANSI C定義了base的可能取值,以及這些取值的符號常量。

(4)返回值

  正常返回:當(dāng)前指針位置。
  異常返回:-1,表示定位操作出錯。

下列是較特別的使用方式:
1) 欲將讀寫位置移動到文件開頭時:fseek(FILE *stream,0,SEEK_SET);
2) 欲將讀寫位置移動到文件尾時:fseek(FILE *stream,0,0SEEK_END);

返回值 當(dāng)調(diào)用成功時則返回0,若有錯誤則返回-1,errno會存放錯誤代碼。
附加說明 fseek()不像lseek()會返回讀寫位置,因此必須使用ftell()來取得目前讀寫的位置。

#include <stdio.h> #include <string.h> struct std_type {int num;char name[20];int age;char class; }stud; int cstufile() {int i;FILE *fp;if((fp=fopen("stufile","wb"))==NULL){printf("The file can't be opened for write.\n");return 0;}for(i=1;i<=100;i++){stud.num=i;strcpy(stud.name,"aaaa");stud.age=17;stud.class='8';fwrite(&stud,sizeof(struct std_type),1,fp);}fclose(fp);return 1; } void main() {int n;FILE *fp;if(cstufile()==0) return;if((fp=fopen("stufile","rb"))==NULL){printf("The file can not be opened.\n");return;}for(n=0;n<100;n+=2){fseek(fp,n*sizeof(struct std_type),SEEK_SET);fread(&stud,sizeof(struct std_type),1,fp);printf("%10d%20s%10d%4c\n",stud.num,stud.name,stud.age,stud.class);}fclose(fp); }

示例代碼:

#include <stdio.h> #include <stdlib.h>#include<stdio.h> void main() {FILE * stream;long offset;fpos_t pos;stream=fopen(“/etc/passwd”,”r”);fseek(stream,5,SEEK_SET);printf("offset=%d/n",ftell(stream));rewind(stream);fgetpos(stream,&pos);printf("offset=%d/n",pos);pos=10;fsetpos(stream,&pos);printf("offset = %d/n",ftell(stream));fclose(stream); } 執(zhí)行 結(jié)果 offset = 5 offset =0 offset=10

ftell(取得文件流的讀取位置)
相關(guān)函數(shù) fseek,rewind,fgetpos,fsetpos
表頭文件 #include<stdio.h>
定義函數(shù) long ftell(FILE * stream);
函數(shù)說明 ftell()用來取得文件流目前的讀寫位置。參數(shù)stream為已打開的文件指針。
返回值 當(dāng)調(diào)用成功時則返回目前的讀寫位置,若有錯誤則返回-1,errno會存放錯誤代碼。
錯誤代碼 EBADF 參數(shù)stream無效或可移動讀寫位置的文件流。
范例 參考fseek()。

?

?

關(guān)于exit()函數(shù)

1. 函數(shù)原型:void exit(int status)

2. 功能說明:exit()函數(shù)使程序立即終止執(zhí)行,同時將緩沖區(qū)中剩余的數(shù)據(jù)輸出并關(guān)閉所有已經(jīng)打開的文件。
3. 參數(shù)說明:status:為0值表示程序正常終止,為非0值表示一個定義錯誤。
4. 返回值:無。

* 關(guān)于feof()函數(shù)

1. 函數(shù)原型:int feof(FILE *fp)
2. 功能說明
   在文本文件(ASCII文件)中可以用值為-1的符號常量EOF來作為文件的結(jié)束符。但是在二進制文件中-1往往可能是一個有意義的數(shù)據(jù),因此不能用它 來作為文件的結(jié)束標(biāo)志。為了能有效判別文件是否結(jié)束,ANSI C提供了標(biāo)準(zhǔn)函數(shù)feof(),用來識別文件是否結(jié)束。
3. 參數(shù)說明:fp:文件指針。
4. 返回值
  返回為非0值:已到文件尾。

  返回為0值:表示還未到文件尾。

?

?

C語言的直接I\O文件操作

?

這是 C 提供的另一種文件操作,它是通過直接 存/取 文件來完成對文件的處理(也就是 系統(tǒng)調(diào)用。更多關(guān)于 系統(tǒng)調(diào)用 和 庫函數(shù) 可以參看 APUE《Advanced Programming in the Unix Environment》),而上面所說流式文件操作是通過緩沖區(qū)來進行操作的(也就是通過庫函數(shù)(庫函數(shù)帶緩沖區(qū),系統(tǒng)調(diào)用不帶緩沖區(qū))來操作文件);流式文件操作是圍繞一個FILE指針來進行,而此類文件操作是圍繞一個文件的“句柄”來進行,什么是句柄呢?它是一個整數(shù),是系統(tǒng)用來標(biāo)識一個文件(在WINDOWS中,句柄的概念擴展到所有設(shè)備資源的標(biāo)識)的唯一的記號。此類文件操作常用的函數(shù)如下表,這些函數(shù)及其所用的一些符號在io.h和fcntl.h中定義,在使用時要加入相應(yīng)的頭文件。

函數(shù) 說明 open() 打開一個文件并返回它的句柄 close() 關(guān)閉一個句柄 lseek() 定位到文件的指定位置 read() 塊讀文件 write() 塊寫文件 eof() 測試文件是否結(jié)束 filelength() 取得文件長度 rename() 重命名文件 chsize() 改變文件長度

?

1.open()
  打開一個文件并返回它的句柄,如果失敗,將返回一個小于0的值,原型是int open(const char *path, int access [, unsigned mode]); 參數(shù)path是要打開的文件名,access是打開的模式,mode是可選項。表示文件的屬性,主要用于UNIX系統(tǒng)中,在DOS/WINDOWS這個參數(shù)沒有意義。其中文件的打開模式如下表。
符號 含義 符號 含義 符號 含義
O_RDONLY 只讀方式 O_WRONLY 只寫方式 O_RDWR 讀/寫方式
O_NDELAY 用于UNIX系統(tǒng) O_APPEND 追加方式 O_CREAT 如果文件不存在就創(chuàng)建
O_TRUNC 把文件長度截為0 O_EXCL 和O_CREAT連用,如果文件存在返回錯誤 O_BINARY 二進制方式 O_TEXT 文本方式 
對于多個要求,可以用"|"運算符來連接,如O_APPEND|O_TEXT表示以文本模式和追加方式打開文件。
例:inthandle=open("c:\\msdos.sys",O_BINARY|O_CREAT|O_WRITE)

2.close()
關(guān)閉一個句柄,原型是int close(int handle);如果成功返回0
例:close(handle)

3.lseek()
  定位到指定的位置,原型是:long lseek(int handle,long offset, int fromwhere);參數(shù)offset是移動的量,fromwhere是移動的基準(zhǔn)位置,取值和前面講的fseek()一樣,SEEK_SET:文件首部;SEEK_CUR:文件當(dāng)前位置;SEEK_END:文件尾。此函數(shù)返回執(zhí)行后文件新的存取位置。
例:
  lseek(handle,-1234L,SEEK_CUR);//把存取位置從當(dāng)前位置向前移動1234個字節(jié)。
  x=lseek(hnd1,0L,SEEK_END);//把存取位置移動到文件尾,x=文件尾的位置即文件長度

4.read()
  從文件讀取一塊,原型是int read(int handle, void*buf, unsigned len);參數(shù)buf保存讀出的數(shù)據(jù),len是讀取的字節(jié)。函數(shù)返回實際讀出的字節(jié)。
例:char x[200];read(hnd1,x,200);

5.write()
  寫一塊數(shù)據(jù)到文件中,原型是int write(int handle,void *buf, unsigned len);參數(shù)的含義同read(),返回實際寫入的字節(jié)。
例:char x[]="I LoveYou";write(handle,x,strlen(x));

7.eof()
  類似feof(),測試文件是否結(jié)束,是返回1,否則返回0;原型是:inteof(int handle);
例:while(!eof(handle1)){……};

8.filelength()
  返回文件長度,原型是long filelength(int handle);相當(dāng)于lseek(handle,0L,SEEK_END)
例:long x=filelength(handle);

9.rename()
  重命名文件,原型是int rename(const char*oldname, const char *newname); 參數(shù)oldname是舊文件名,newname是新文件名。成功返回0
例:rename("c:\\config.sys","c:\\config.w40");

10.chsize();
  改變文件長度,原型是int chsize(int handle, longsize);參數(shù)size表示文件新的長度,成功返回0,否則返回-1,如果指定的長度小于文件長度,則文件被截短;如果指定的長度大于文件長度,則在文件后面補''\0''。
例:chsize(handle,0x12345);
如果熟悉匯編可能會發(fā)現(xiàn)這種方式和匯編語言的DOS功能調(diào)用句柄式文件操作很像,比如open()就像DOS服務(wù)的3CH號功能調(diào)用,其實這種操作還有兩種類型的函數(shù)就是直接用DOS功能來完成的,如_open(),_dos_open()等等。有興趣可自已查詢BCB的幫助。
  同流式文件操作相同,這種也提供了Unicode字符操作的函數(shù),如_wopen()等等,用于9X/NT下的寬字符編程,有興趣可自已查詢BCB的幫助。
  另外,此種操作還有l(wèi)ock(),unlock(),locking()等用于多用戶操作的函數(shù),但在BCB中用得并不多,我就不介紹了,但如果要用C來寫CGI,這些就必要的常識了,如果你有這方面的要求,那就得自已好好看幫助了.

setbuffer(設(shè)置文件流的緩沖區(qū))
相關(guān)函數(shù) setlinebuf,setbuf,setvbuf
表頭文件 #include<stdio.h>
定義函數(shù) void setbuffer(FILE * stream,char * buf,size_t size);
函數(shù)說明 在打開文件流后,讀取內(nèi)容之前,調(diào)用setbuffer()可用來設(shè)置文件流的緩沖區(qū)。參數(shù)stream為指定的文件流,參數(shù)buf指向自定的緩沖區(qū)起始地址,參數(shù)size為緩沖區(qū)大小。
返回值

setlinebuf(設(shè)置文件流為線性緩沖區(qū))
相關(guān)函數(shù) setbuffer,setbuf,setvbuf
表頭文件 #include<stdio.h>
定義函數(shù) void setlinebuf(FILE * stream);
函數(shù)說明 setlinebuf()用來設(shè)置文件流以換行為依據(jù)的無緩沖IO。相當(dāng)于調(diào)用:setvbuf(stream,(char * )NULL,_IOLBF,0);請參考setvbuf()。
返回值

setvbuf(設(shè)置文件流的緩沖區(qū))
相關(guān)函數(shù) setbuffer,setlinebuf,setbuf
表頭文件 #include<stdio.h>
定義函數(shù) int setvbuf(FILE * stream,char * buf,int mode,size_t size);
函數(shù)說明 在打開文件流后,讀取內(nèi)容之前,調(diào)用setvbuf()可以用來設(shè)置文件流的緩沖區(qū)。參數(shù)stream為指定的文件流,參數(shù)buf指向自定的緩沖區(qū)起始地址,參數(shù)size為緩沖區(qū)大小,參數(shù)mode有下列幾種
_IONBF 無緩沖IO
_IOLBF 以換行為依據(jù)的無緩沖IO
_IOFBF 完全無緩沖IO。如果參數(shù)buf為NULL指針,則為無緩沖IO。
返回值

?

?

?

總結(jié)

以上是生活随笔為你收集整理的C 和 C++ 文件操作详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。