1. 程式人生 > >C++讀寫檔案操作

C++讀寫檔案操作

原文來自:http://blog.csdn.net/study16/article/details/5879428

來源:http://www.javaeye.com/topic/383903

讀 《C++ Primer Plus》第174-7

一     頭 檔案關係:

C++在標頭檔案fstream(fstream.h)中定義了ifstream類和oftream類,以及用於I/O同步的fstream。這些類都是從標頭檔案iostream中的類派生而來,iostream的基類是istream,ostream。對於大多數實現來說,包含fstream則自動包含iostream檔案。ofstream的基類是ostream,iftream

類的基類是istream。檔案流類從ios_base類中繼承了一個流狀態成員以及報告流狀態的 方法。

二     創 建讀寫流物件的方法:

1  建構函式

                   1.              ifstream fin;      fin.open(“jar.dat”);     或者 ifstram fin(“jar.dat”);

                            ofstream同理

                            使用方法可同cin,cout.cin>>name;cout<<name;

2.      檔案模式的使用 方法:

         ifstraem fin(“temp.txt”,mode);

         ofstream fout;

fout.open(“temp.txt”,mode);

2)   open函式

         在fstream類中,有一個成員函式open(),就是用來開啟檔案的,其原型是:

void yWXz(const char* filename,int mode,int access); 
引數說明:   
  
filename:  要開啟的檔名 mode:    要開啟檔案的方式 access:   開啟檔案的屬性 
  開啟檔案的方式在類

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

常量

含義

常量

含義

ios_base::in

開啟檔案,以便 讀取

ios_base::app

追加到檔案尾

        out

              寫 入

        trun

檔案存在,則截 短檔案

        ate

        ,並移到檔案尾

        binary

二進位制檔案

ios::nocreate: 不建立檔案,所以檔案不存在時開啟 失敗 

ios::noreplace:不覆蓋檔案,所以開啟檔案時如果檔案存在失敗

ios::trunc:  如果檔案存在,把檔案長度設為0

開啟檔案的屬性取值是:   

  0:普通檔案,開啟訪問

1:只讀檔案

2:隱含檔案

4:系統檔案

  可以用或者“+”把以上屬性連線起來 ,如31|2就 是以只讀和隱含屬性開啟檔案。   

  例如:以二進位制輸入方式開啟檔案c:/config.sys 

fstream file1;

file1.open("c://config.sys",ios::binary|ios::in,0); 

    如果open函式只有檔名一個引數,則是以讀/寫普通檔案開啟,即:   

file1.open("c://config.sys");<=>file1.open("c://config.sys",ios::in|ios::out,0); 

    另外,fstream還有和open()一樣的建構函式,對於上例,在定義的時侯就可以 開啟檔案了:   

    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");//以輸出方式開啟 檔案

三     檢 查檔案是否開啟的方法:

a)      if(fin.fail());

b)      if(!fin.good());

c)      if(!fin)        //根據fin.good()來設定自己的bool

d)      is_open() //能夠檢測到一不合適的文字模式開啟檔案時失敗的錯誤和上述good()測到的各種錯誤

         fin.good();//正常讀取檔案時返回true

         fin.fail();/在檔案到達結尾或者出現其他輸入錯誤如記憶體不足時返回true

         fin.eof();//當檔案到達結尾的返回true

         fin.bad();//出現無法識別的故障(如硬碟故障)時返回true

四     使 用命令列引數的方法:

          int main(int argc,char* argv[]){…}    第一個引數為命令和引數個數的和,第二個引數為引數陣列

          fin.clear()         將檔案與ifstream物件關聯起來時,自動重置狀態。不一定要 求,但是無害。

五     文 件模式常量:

六     C++C的檔案打 開模式

C++模式

C模式

含義

ios_base::in

“r”

開啟一讀取

ios_base::out

“w”

等價於ios_base::out|ios_base::trunk(有時可以省略)

out|trunc

“w”

開啟一些如文 件,如果存在,則擷取檔案

out|app

“a”

開啟以寫入,只 追加

in|out

“r+”

開啟以寫入,在 檔案讀取的位置寫入

in|out|trunc

“w+”

開啟以讀寫,如 果存在,則首先擷取檔案

out|binary

cmodeb

C++mode和二進位制模式開啟,例如ios_base::in|ios_base::binary成為“rb”

out|ate

“cmode”

以指定的模式打 開,並已到檔案尾。C則需要使用 獨立的函式呼叫。例如,ios_base::in|ios_base::ate則被轉換為“r”C函式呼叫fseek(file,0,SEEK_END);

對於app模式,只能追加,但是不能修改原來已經存在的資料, 要是其能修改,則需要與out模 式組合,即app|out。對於 已經處理到末尾的檔案,eof位 將被被設定為1,因此,如果想對 檔案再作修改,則需要呼叫函式fout.clear()終止流狀態,否則禁止對檔案作進一步讀寫操作。

七     文 件讀寫:

1)   操縱符 功能 輸入/輸出

dec 格式化為十進位制數值資料 輸入和輸出

endl 輸出一個換行符並重新整理此流 輸出

ends 輸出一個空字元 輸出

hex 格式化為十六進位制數值資料 輸入和輸

出 oct 格式化為八進位制數值資料 輸入和輸出

setpxecision(int p) 設定浮點數的精度位數 輸出

         2)   基本 方法

         ①put()

    put()函式向流寫入一個字元,其原型是ofstream &put(char ch),使用也比較簡單,如file1.put('c');就是向流寫一個字元'c'。   

②get()

    get()函式比較靈活,有3種常用的過載形式:   

    一種就 是和put()對應的形式:ifstream &get(char &ch);功能是從流中讀取一個字元,結果儲存在引用ch中,如果到檔案尾,返回空字元。如file2.get(x);表示從檔案中讀取一個字元,並把讀取的字元儲存在x中。   

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

    還有一種形式的原型是:ifstream &get(char *buf,int num,char delim='/n');這種形式把字元讀入由 buf指向的陣列,直到讀入了 num 個字元或遇到了由 delim 指定的字元,如果沒使用 delim 這個引數,將使用預設值換行符'/n'。例如:   

    file2.get(str1,127,'A');//從檔案中讀取字元到字串str1,當遇到字元'A'或讀取了127個 字元時終止。  

讀寫資料 塊(read, write

    要讀寫 二進位制資料塊,使用成員函式read()write()成員函式,它們原型如下:

read(unsigned char *buf,int num);

write(const unsigned char *buf,int num);

read()從檔案中讀取 num 個字元到 buf 指向的快取中,如果在還未讀入 num 個字元時就到了檔案尾,可以用成員函式 int gcount();來取得實際讀取的字元數;而 write() buf 指向的快取寫 num 個字元到檔案中,值得注意的是快取的型別是 unsigned char *,有時可能需要型別轉 換。   

  例:

out.write(str1,strlen(str1));//把字串str1全部寫到yyy.yyy

in.read((unsigned char*)n,sizeof(n));//xxx.xxx中讀取指定個整數,注意型別轉換

八     隨 即讀取檔案的函式

         和C的檔案操作方式不同的是,C++ I/O系統管理兩個與一個檔案相聯絡的指標。一個是 讀指標,它說明輸入操作在檔案中的位置;另一個是寫指標,它下次寫操作的位置。每次執行輸入或輸出時,相應的指標自動變化。所以,C++的檔案定位分為讀位置和寫位置的定位,對應的成員函式是 seekg()和 seekp()seekg()是設定讀位置,seekp是設定寫位置。它們最通用的形式如下:   

      istream &seekg(streamoff offset,seek_dir origin);

ostream &seekp(streamoff offset,seek_dir origin);

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

ios::beg:  檔案開頭

ios::cur:  檔案當前位置

ios::end:  檔案結尾

    這兩個 函式一般用於二進位制檔案,因為文字檔案會因為系統對字元的解釋而可能與預想的值不同。

  例:

file1.seekg(1234,ios::cur);//把檔案的讀指標從當前位置向後移1234個位元組

file2.seekp(1234,ios::beg);//把檔案的寫指標從檔案開頭向後移1234個字

程式碼展示

1)   覆蓋操作:(tellpseekp

outfile.write ("This is an apple",16);

pos=outfile.tellp();

outfile.seekp (pos-7);

outfile.write (" sam",4);

輸出:This is a sample

2)   讀取整個檔案到緩衝(seekg,tellg)

  int length;

  char * buffer;

  ifstream is;

  is.open ("test.txt", ios::binary );

  // get length of file:

  is.seekg (0, ios::end);

  length = is.tellg();

  is.seekg (0, ios::beg);

  // allocate memory:

  buffer = new char [length];

  is.read (buffer,length);

  is.close();

  cout.write (buffer,length);

  delete[] buffer;

九     文 件操作結構體

         struct   DATA {  

       int   n;  

       char   a;  

  };

  ostream&   operator   <<(ostream&   os,   DATA&   data) {   
         os<<data.a;   
         os<<data.n;   
         return   os;   
  }   
  istream&   operator   >>(istream&   os,   DATA&   data) {   
         os>>data.a;  

         os>>data.n;  

         return   os;  

  }

十     使 用臨時檔案(cstdio(stdio.h))

tmpname(pasName);生成生成與當前目錄不重名的字串存於pasName中,pasName的長度最多為L_tmpnam,最多生成TMP_NAM個不同的檔名。
===========================
2C/C++讀寫檔案小結 1-4全集
http://rf0007.spaces.live.com/blog/cns!DBC9143ACED2EB3A!117.entry

因為工作需要,最近到處摘抄C/C++關於讀寫 檔案的例子,這裡留個小結,以備後用。
讀檔案的流程是大致是如此的:
建立一個操作檔案的指標 
*fd => 用某種方式(讀//讀寫/追加等等)開啟檔案 => 對檔案做相應的操作。
示例檔名為
readtxt.txt,同程式置於相同目錄下。 檔案內容為:
hello,world
my name is rf0007

 純C的讀文字檔案
定 義一個檔案指標
FILE *fd;
fopen開啟一個文字檔案,fopen的第一個引數為檔案路和檔名,第二個引數定義的是開啟檔案 的方式,這些引數實在是記不住,具體的如下:

參 數

全寫

意義

r

read

w

write

a

append

追加

t

text

文字檔案,可省略

b

binary

二 進位制檔案

rt

只讀,文字檔案

wt

只寫或建立,文字檔案

at

在檔案末尾 追加,文字檔案

rb

只讀,二進位制檔案

wb

只寫或建立,二進位制檔案

ab

在檔案末尾 追加,二進位制檔案

rt+

可讀可寫,文字檔案

wt+

可讀可寫或建立,文字檔案

at+

可 讀可寫,在檔案的末尾追加,文字檔案

rb+

可讀可寫,二進位制檔案

wb+

可讀可寫或建立,二進位制檔案

ab+

可讀可寫,在檔案的末尾追加,二進位制檔案

fd = fopen("txtfile.txt","r");
執行完
fopen後,需要判斷一下,此檔案是否確實被打開了。

if(NULL == fd)printf("
檔案未被開啟");
接下來就可以進行檔案的操作了。
讀檔案的函式有好幾 個,
fread,fscanf,fgets。它們之間是有區別的:
fread
是以塊的方式來讀取資料,按照指定的長度和指定的次數來讀,讀完後的 資料是按照地址的方式來儲存的,所以,比較適合用它來讀二進位制數,因為程式設計師比較清楚的知道自己要讀多少的資料。
fgets
是以串的方式來讀取數 據,從資料檔案中讀取不超過N-1個字元的數,讀入的資料在最後一個字元後會加上一個截止符'/n',如果中間出現了回車,就會截止了。所以可以用 fgets來讀入一行的文字資料,應該是相當好用的。
fscanf
fgets類似,不過它是按照格式來讀的,跟scanf一樣。比如說,指定一 個%d,那麼它就讀入一個整型的值;如果指定一個%s,那麼它遇到一個空格也會停止的。
以下是一個實際的程式碼,用三種方式來完成檔案的讀取。
#include <stdio.h> 
int main()
{
    FILE *fd;
    char buf[64];
    fd = fopen("txtfile.txt","rb");
    if(NULL == fd)
    {
      printf("read file error!");
      return 0;       
    }
    printf("read file success!/n");
    while(!feof(fd))
    {
        /*method 1
      fgets(buf,64,fd);
      printf("%s/n",buf);
      */
      /*method 2
      fread(buf,64,1,fd);
      printf("the %dth time: %s /n ",count,buf);
      */
      fscanf(fd,"%s",buf);
      printf("%s/n",buf);
    }   
    fclose(fd);
    return 1;
}

C的寫文字檔案
與 上文中描述的讀檔案相似,寫檔案也有這麼幾個函式
fputs,fwrite,fprintf,其中fputsfgets對應,fwritefread 對應,fscanffprintf對應。同樣的,它們之間也是有區別的。fputs多用於寫入成行的文字檔案,fwrite用於寫入二進位制文 件,fprintf用於寫入格式化的資料。
以下為示例程式原始碼:

#include <stdio.h>
int main()
{
    FILE *fd;
    char buf[64];
    char *str1 = "hello,world/n";
    char *str2 = "my name is rf0007";
    fd = fopen("txtfile.txt","wt");
    if(NULL == fd)
    {
        printf("open file error!/n");
        return 0;    
    }
    /*method 1
    fputs(str1, fd);
    fputs(str2, fd);
    */

    /*method 2
    fwrite(str1, strlen(str1), 1, fd);
    fwrite(str2, strlen(str2), 1, fd);
    */

    fprintf(fd, "%s", str1);
    fprintf(fd, "%s", str2);
    
    fclose(fd);
    return 1;    
}

C讀 寫二進位制檔案
讀寫二進位制檔案與讀寫文字檔案本身沒有太大的區別,只不過能使用的函式有區別而已。在上文中提到使用的 
fread,fwrite,fgetc,fputc都可以用來操作二進位制檔案。以下的例子是將一串資料寫入二進位制檔案,然後再將其還原出來。
#include <stdio.h> 
int main()
{
    FILE *fd;
    int iVal;
    float fVal;
    char *cVal = "hello,world";
    int count;
    //write file
    fd = fopen("file1.dat","wb");
    if(NULL == fd)
    {
        printf("1.open file error!/n");
        return 0;
    }
    fVal = 1.1;
    int i;
    for(i=0; i<5; i++)
    {
        iVal = 100+i;
        printf("iVal(%d)=%d /n",i,iVal);
        fwrite(&iVal, sizeof(int), 1, fd);
        fVal = 1.1+i;
        fwrite(&fVal, sizeof(float), 1, fd);
        printf("fVal(%d)=%f /n",i,fVal);            
    }
    fclose(fd);
    //read file
    fd = fopen("file1.dat","rb");
    if(NULL == fd)
    {
        printf("2.open file error!/n");
        return 0;
    }
    printf("read file ==========/n");
    i = 0;
    while(!feof(fd))
    {
        fread(&iVal, sizeof(int), 1, fd);
        printf("iVal(%d)=%d /n",i,iVal);
        fread(&fVal, sizeof(float), 1, fd);
        printf("fVal(%d)=%f /n",i,fVal);
        i++;    
    }
    fclose(fd);
    return 1;    
}

相關推薦

C++檔案操作

原文來自:http://blog.csdn.net/study16/article/details/5879428 來源:http://www.javaeye.com/topic/383903 讀 《C++ Primer Plus》第17章4-7節 一     頭 

C檔案操作總結

FILE *fopen( const char *filename, const char *mode ); 一、對已經存在的檔案進行讀寫 mode: “r”—— Opens for reading. “r+”—- Opens for

(C/C++) FILE 檔案操作

per use () eat col 在操作 har 意思 etl 在C/C++ 讀寫檔案操作比較常見應該是利用 FILE、ifstream、ofstream 在這篇筆記裡頭記錄 FILE、fstream 使用方法及操作 1 #include <iostream&

C#檔案的所有方法總結

計算機在最初只支援ASCII編碼,但是後來為了支援其他語言中的字元(比如漢字)以及一些特殊字元(比如€),就引入了Unicode字符集。基於Unicode字符集的編碼方式有很多,比如UTF-7、UTF-8、Unicode以及UTF-32。在Windows作業系統中,一個文字檔案的前幾個位元組

c/c++ /檔案

利用c++的stream類 標頭檔案:#include <fstream> 1.讀檔案 string strRes; string strPath = “/opt/test/test.txt”; if (access(strPath .c_str(),

C#檔案宜取方式.md

C#讀寫檔案宜取方式 首先,不推薦用如下方式讀寫 //讀 using (FileStream fs = File.OpenRead(filePath)) { byte[] b = new byt

node.js的fs核心模組檔案操作 -----由淺入深

https://www.cnblogs.com/null11/p/7499091.html node.js的fs核心模組讀寫檔案操作 -----由淺入深 node.js 裡fs模組 常用的功能 實現檔案的讀寫 目錄的操作 - 同步和非同步共存 ,有非同步不用同步 - fs.

c++檔案設定的位置

檔案定位  和C的檔案操作方式不同的是,C++ I/O系統管理兩個與一個檔案相聯絡的指標。一個是讀指標,它說明輸入操作在檔案中的位置;另一個是寫指標,它下次寫操作的位置。每次執行輸入或輸出時,相應的指標自動變化。所以,C++的檔案定位分為讀位置和寫位置的定位,對應的成員函式是

Qt總結之五:檔案操作

  一、簡介        通過QFile、QDir、QFileInfo和QFileSystemWatcher類簡單介紹對檔案和目錄的一些操作。對文字流和資料流沒有太多的介紹,還有一些Qt資源、統一資源定位符、緩衝區可以在以後應用中加上。

RandomAccessFile隨機檔案操作類講解

private FileAccessI fileAccessI; private File file = null; private int lstart = 0; String dirName = ""; System.out.println("下載時接收到的內容:" + new String(byt

C++檔案時,0A轉化為0D 0A

用C++寫東西,需要往檔案裡寫資料,很簡單的程式碼,大概是這個樣子:#include <fstream>using namespace std;int _tmain(int argc, _TCHAR* argv[]){ ofstream fout; fout.o

C++檔案儲存至容器list中

C++讀寫檔案及容器list基本操作       大家在開始入門C/C++時,都要練習個學生管理系統啥的,主要都為了進一步掌握所學知識,並能使用這些知識。其中這個小專案的重難點就在資料的操作了,其中如

C#檔案中文亂碼

讀寫檔案的時候,檔案中存在中文字元; 直接讀取會出現亂碼,然後一搜索網上的各種亂碼處理方法,大多數是對讀取的string進行轉碼。 其實有一種簡單的方法,就是直接在讀取的時候就設定編碼,程式碼如下:

java(JSP)檔案操作

JAVA讀寫指定檔案內容,工作中用到的,放在這裡給大家分享一下. 以下為讀寫檔案類: package com.hexun.wap.zgpack; import java.io.BufferedReader;import java.io.FileReader;import ja

Java IO操作——簡單瞭解RandomAccessFile隨機檔案操作類的使用

學習目標 掌握RandomAccessFile類的作用 可以使用RandomAccessFile讀取指定位置的資料 RandomAccessFile類的主要功能是完成隨機讀取功能,可以讀取指定位置的

C++檔案,處理UTF8檔案,處理GBK中文字元

讀檔案 //從檔案中提取詞典 void getLexiconFromTrainData(char* filepath){ maxLength = 0; lexicalItemCount=0; allSentenceCount=0; wordCount=0

C檔案--刪除指定的一行

#include <stdio.h>#include <string.h> void InsertLine(char* FileName, int Line, char str[256]);void deleteLine(char* FileName,

C#檔案總結

方式一:用FileStream //例項化一個儲存檔案對話方塊 SaveFileDialog sf = new SaveFileDialog(); //設定檔案儲存型別 sf.Filter = "txt檔案|*.txt|所有檔案|*.*"; //如果使用者沒有輸入副檔名,自動追加字尾 sf.AddExten

C#檔案--專案案例

//寫檔案–SaveFileDialog private void Write() { string file; System.Windows.Forms.SaveFileDialog sfd = new S

C++檔案相關(包括一行行讀取資料,讀取每一行資料的第一個數)的函式

1.setprecision()函式的使用及標頭檔案? 2.利用getline()怎麼讀取一行資料,換行符是否讀入了? 3.怎麼使用串流實現對string字串的輸入輸出? 寫資料到txt檔案 //其中的setprecision()函式在標頭檔案iomanip 中