C++雜談之關於文件操作的若干問題

原文地址

http://blog.csdn.net/plzhou/article/details/20486305




C++雜談之關於文件操作的若干問題


一、文本文件和二進制文件

      (1)文件只是計算機內存中二進制表示的數據在外部存儲介質上的另一種存放方式。文件通常可以分爲二進制文件和文本文件。

      (2)將數據存儲在文件中時,可以將其存儲爲文本格式或二進制格式。文本格式是指將所有內容(甚至數字)都存儲爲文本。例如,以文本格式存儲-2.324216e+07時,將存儲該數字包含的13個字符,這需要將浮點數的計算機內部表示轉換爲字符,這正是<<插入操作符完成的工作。另一方面,二進制格式指的是存儲值的計算機內部表示。也就是說,計算機不是存儲字符,而是存儲這個值的64位double表示。

      (3)對於字符來說,二進制表示和文本表示都是一樣的,即字符的ASCII碼的二進制表示。

      (4)對於數字來說,二進制表示和文本表示有着很大的差別。

      (5)使用二進制文件模式時,程序將數據從內存傳輸給文件(反之亦然)時,將不會發生任何隱藏的轉換,而默認的文本模式並非如此。


二、文本方式和二進制方式

      (1)當按照文本方式向文件中寫入數據時,一旦遇到“換行”字符(ASCII碼爲10),則會轉換爲“回車——換行”(ASCII碼分別爲13、10)。在讀取文件時,一旦遇到“回車——換行”的組合(連續的ASCII碼爲13、10),則會轉換爲換行字符(ASCII碼爲10)。

      (2)當按照二進制方式向文件中寫入數據時,則會將數據在內存中的存儲形式原樣輸出到文件中。

      (3)由於文本方式和二進制方式在讀取和寫入數據時的差異,所以在寫入和讀取文件時要保持一致。如果採用文本方式寫入,應採用文本方式讀取;如果採用二進制方式寫入數據,在讀取時也應採用二進制方式。否則就會出現問題。

      (4)不管是文本文件還是而二進制文件,如果統一採用二進制方式進行寫入和讀取,則是不會出錯的。因爲這種讀取和寫入時嚴格按照一個字節一個字節進行的。

      注:讀者一定要注意文本文件和二進制文件,文本方式和二進制方式之間的區別,不要混淆。不管是文本文件還是二進制文件,都可以採用二進制方式或文本方式打開,然後進行寫入或讀取。但是,對於二進制文件來說,如果以文本方式讀取時,可能出現一些問題。

      文本文件和二進制文件,文本方式和二進制方式之間是沒有關係的,他們描述了文件的不同方面。前者描述了文件的存儲方式,後者描述了文件的打開方式(換行符有區別)。


三、格式化操作和非格式化操作

 

C

C++

格式化操作

實現函數:fscanf , fprintf,sscanf,sprintf

實現方式:利用格式字符串進行相應格式的轉換

實現函數:<< , >>

實現方式:是通過對插入和提取運算符的重載實現的

讀取時(數值):將字符串轉換成數值

寫入時(數值):經數值轉化爲字符串形式

非格式化操作

實現函數:fread , fwrite

實現方式:以二進制方式直接寫入一定字節長度的數據

實現函數:.read ,  .write

實現方式:以二進制方式直接寫入一定字節長度的數據

讀取寫入:數值和字符串時都不會進行任何的轉換

        格式化操作和非格式化操作主要區別在於對讀取寫入數據的操作,前者會對數據進行相應的格式化,而後者原樣輸入(只是相對來說,其實是有變化的,如果內存單元式char類型,則不會變化,若是short,int等類型,則會進行相應的變化,具體如下說明)。 

 

注:關於fread、fwrite和.read、.write的說明:

      (1)(在intel系統中,最低位在前,最高位在後),當使用fwrite,.write寫入數據時,char類型直接寫入,short,int,long類型在會倒置,即最低位在前,最高位在後。例如:十六進制:00 01 00 00 (即:00 00 01 00 也就是2的8次方 ),十進制:256. 

      當使用fread,.read讀取數據時,char類型直接讀入,short,int,long類型會將文件中的數據倒置,恢復到正常的順序(是寫入的逆過程),以便正確的讀入數據。

      (2)fread(const void* buf,int size,int count,FILE* file)

                fwrite(const void*buf,int size,int count,FILE* file)

      按照上述規則進行讀取寫入數據,讀寫數據大小爲size*count。當分配的內存爲結構體或者數組時,只要讀寫的數據長度正確,則函數會根據數據中具體的元素的數據類型應用上述規則。

      總結:如果內存單元式char類型,則不會變化,若是shortint等類型,則會進行相應的變化,(造成的原因:IntelMorola系統的存儲方式區別:Little EndianBig Indian)

      (1)讀取示例

            十六進制: 00 01 00 02 0003

            讀取函數:

            short buf[3];

            fread((const void*)buf,2,3,fp);

            for(int i=0;i<3;i++)

            cout<<buf[i]<<endl;

            則顯示結果爲:256,512,768

      (2)寫入示例

            struct test{char a;shot b;intc;long d}

            test data={‘a’,1,2,3};

            fwrite((constvoid*)&data,1,sizeof(data),fp)

            則文件的十六進制顯示爲:61 01 00 02 00 00 00 03 00 00 00


四、文本文件,二進制文件中的格式化、非格式化操作

 

操作

實現

文本文件

讀寫數值:

(可以通過格式     化和非格式化實現)

格式化操作:fscanf,fprint;<<,>>

將字符串形式的數值直接轉化爲相應的數據類型的數據,讀取長度:從第一個非空格開始直到與數字不相同的字符爲止

示例:文件中有:1234.5678

C:

double val;

fscanf(fp,”%lf”,&val);

C++:

double val;

fp>>val;

非格式化操作:fread,fprint; .read, .write(注意上述說明,最好採用char元素內存,則不會存在變化)

首先先將文件中的數值以字符串的形式完整讀入,然後再將字符串轉換成相應數據類型的數據,讀取長度:自己指定

示例:文件中有:1234.5678

char buf[9];

fread(buf,1,8,fp);

double val;

sscanf(buf,”%lf”,&val);

讀取字符串:

格式化操作和非格式化操作都是相同的,不會對字符串進行相應的轉化,一般使用fgets,.gets讀取字符串,主要是可以指定讀取長度。直接用>>,將讀入全部,因爲文本文件都是字符串。

二進制文件

讀取數值:

由於存儲時直接存儲數值的二進制形式,所以不需要進行相應的轉化,只需知道數據的格式。

只能通過非格式化操作實現

讀取字符串:

文件直接存儲字符串的ASCII碼值得二進制形式,所以直接讀取一定長度的字符串即可。

      文本文件和二進制文件,文本方式和二進制方式,以及格式化操作和非格式化操作之間是沒有嚴格的關係的,他們描述了文件的不同方面。前者描述了文件的存儲方式,中間者描述了文件的打開方式,而後者描述了在對文件讀取寫入數據時對數據(尤其是數值)的處理方式。

  


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章