IO流總結

C++的I/O流體系

   繼承關係:

   ios <-- istream/ostream

   |--> istream <-- istrstream/ifstream/iostream

   |--> ostream <-- ostrstream/ofstream/iostream

   |--> iostream <-- strstream/fstream

   

   istream及其子類支持輸入操作

   ostream及其子類支持輸出操作

   由istream和ostream共同派生的子類iostream既支持輸入也支持輸出。

   

1.通過ofstream類單參(文件路徑)構造函數可以打開一個文件用於向文件中輸出,如果文件不存在,該類的構造函數將以缺省的方式創建文件;

   如果文件存在,進行覆蓋

2.ofstream的兩參數(文件路徑,打開模式openmode)版本

   ios::in:打開文件用於從文件中讀取

   ios::out:打開文件用於向文件中寫入

   ios::app:打開文件用於向文件中追加

   ios::ate:打開文件,把文件位置設置到文件尾部,用於從文件讀取

   // 在打開文件流時使用ios::ate選項,將文件的get位置置於文件尾

   ifstream ifs ("文件路徑", ios::binary | ios::ate);

   if (! ifs)

   PrintError (__FILE__, __LINE__, "Cannot open input file");

   size_t uBytes = ifs.tellg (); // 通過tellg()函數獲取當前的get位置, 以此計算出文件的總字節數

   char* pcBuffer = new char[uBytes]; // 有了總字節數,我們就可以分配足 夠的內存,一次性地讀取文件的全部內容

   ifs.seekg (ios::beg); // 在讀取之前一定要將文件的 get位置重置於文件起始處

   ifs.read (pcBuffer, uBytes);//讀取文件內容

   ios::trunc: 打開文件的同時刪除其原有內容,用於向文件中輸入

   ios::binary:以二進制模式打開文件,用於輸入/輸出

   ofstream ofs ("xxx", ios::out|ios::trunc|ios::binary);

   if (! ofs)

3.ifstream和ofstream用法基本相同,用於從文件中讀取

   但是ifstream要求指定的文件必須存在

4.輸入流的提取操作>>在格式化提取的過程中,以空格、製表符、換行分隔

5.fstream以讀和寫(默認)的方式打開一個文件時,文件必須存在

6.tellg/tellp:獲取當前文件位置(包括\n等)的下一個

   p表示put、g表示get

   tellp在將get位置調整到文件開始的同時,也改變了put位置

   seekg/seekp:設置當前文件的get/set位置

   1.單參: seekg(0)與seekg(ios::beg)完成相同的任務

   2.雙參:

   第一個參數代表相對於第二個參數所指定位置的偏移量:

   ios::beg:文件頭如:fs.seekg (5, ios::beg);//從文件頭(開始下標爲0)開始數5個字符

   如:1234  56.78  apples;//即5數字開始操作

   ios::end:文件尾

   ios::cur:當前位置如:fs.seekg (-6, ios::cur);

   在上面的情況下:tellp/tellg都獲取值爲:0

   如果文件位置被移到了文件的起始位置之前或結束位置之後,那麼該文件流將進入一種錯誤狀態。

   這時程序對這個流所做的更進一步處理將會被暫停,直到我們通過clear() 函數清除了這種錯誤狀態爲止。

   

   如:

   #include <iostream>

   #include <fstream>

   using namespace std;

   int main (int argc, char* argv[]) {

       ofstream ofs1 ("ex01.txt");

       if (! ofs1)

       cerr << "Cannot open output file" << endl;

       ofs1 << 1234 << " " << 56.78 << " " << "apples" << '\n';

       ofs1.close ();

       ofstream ofs2 ("ex01.txt", ios::app);

       if (! ofs2)

       cerr << "Cannot open output file" << endl;

       ofs2 << "append_a_line\n";

       ofs2.close ();

       ifstream ifs1 ("ex01.txt");

       if (! ifs1)

       cerr << "Cannot open input file" << endl;

       int n;

       double f;

       string str1, str2;

       ifs1 >> n >> f >> str1 >> str2;

       ifs1.close ();

       cout << n << " " << f << " " << str1 << " " << str2 << endl;

       ////////////////////////////////////////////////////////////

       fstream fs ("ex02.txt", ios::in | ios::out);

       if (! fs)

       cerr << "Cannot open file" << endl;

       fs << 1234 << " " << 56.78 << " " << "apples" << '\n';

       cout << fs.tellg () << endl;//獲取當前文件位置

       cout << fs.tellp () << endl;//獲取當前文件位置

       fs.seekg (5, ios::beg);//同seekp,都是設置當前文件位置

       fs << 1;

       fs.seekg (-6, ios::cur);

       cout << fs.tellg () << endl;

       cout << fs.tellp () << endl;

       int n;

       double f;

       string str;

       fs >> n >> f >> str;

       fs.close ();

       cout << n << " " << f << " " << str << endl;

       return 0;

   }

7.io的非格式化:

   (1).ofs.put(char);//一次寫入一個字符

   (char = ifs.get()) != EOF//一次獲取一個字符,不爲文件結尾

   (2).get()的三參數:定界符並不被提取,但文件位置會停在定界符處,下次讀取會發生錯誤

       char sz[4];

       while (ifs.get (sz, sizeof (sz), '\n'))//自定義'\n'爲定界符

       {

           cout << sz;

           cout.flush ();//刷新輸入輸出纔可能顯示出來(字符少的時候)

           

           //注意大小爲4的sz可能沒有被填滿,因爲定界符不被get讀取,所以要跳過

           if (ifs.peek () == '\n')//讀當前位置的字符,但不改變文件位置

           ifs.ignore ();//掠過當前位置的字符,文件位置後移

       }

       if (! ifs.eof ())//當前是否到了文件結尾

           cerr << "Cannot read input file 1" << endl;

       ifs.clear ();

   (3).getline():可以自動掠過定界符,但當其試圖讀取第二個參數-1個字符時會發生錯誤

       因爲當文件結束的時候,可能沒有填滿第二個參數-1個字符,這時又結束了(讀取不到字符),那麼就會出錯

       char szLarge[8];

       while (ifs.getline (szLarge, sizeof (szLarge), '\n'))

       cout << szLarge;

       if (! ifs.eof ())//當前是否到了文件結尾

       cerr << "Cannot read input file" << endl;

8.字節流:

   read(char*, size_t)/write(char*, size_t)

   如:

   char caBuffer[256];

   while (ifs.read (cbBuffer, sizeof (cbBuffer)){

       ofs.write (cbBuffer, sizeof (cbBuffer));

   }

   //可通過gcount()函數推斷出實際讀到byBuffer緩衝區中的字節數。

   if (ifs.eof ())//進入某種錯誤狀態時亦返回false

      ofs.write (cbBuffer, ifs.gcount ());

   else

      cerr << "error!" << endl;

9.流函數:

   #include <math.h>

   #include <iostream>

   #include <iomanip>

   #include <fstream>

   using namespace std;

   int main (int argc, char* argv[]) {

       cout << sqrt (2) << endl;//1.41421

       cout.precision (10);//設置小數點精度,區別不帶參數的函數(返回精度)

       cout << sqrt (2) << endl;//1.414213562

       cout << setprecision (10) << sqrt (2) << endl;//1.414213562

       cout << sqrt (2) << endl;//1.414213562

       cout << cout.precision () << endl;//10

       cout << setprecision (2) << 1.24 << ", " << 1.25 << ", " << 1.26 << endl;//1.2, 1.3, 1.3

       cout << oct << 127 << endl;//177

       cout << hex << 127 << endl;//7f

       cout << dec << 127 << endl;//127

       cout << setw (7)/*注意這個函數不保存到下面的設置*/ << oct << 127 << endl;//177

       cout << setw (7) << hex << 127 << endl;//7f

       cout << setw (7) << dec << 127 << endl;//127

       //流控制符

       cout << setfill ('#') << setw (7) << oct << 127 << endl;//####177

       cout << setfill ('@') << setw (7) << hex << 127 << endl;//@@@@@7f

       cout << setfill ('%') << setw (7) << dec << 127 << endl;//%%%%127

       cout << left << setfill ('#') << setw (7) << oct << 127 << endl;//177####

       cout << left << setfill ('@') << setw (7) << hex << 127 << endl;//7f@@@@@

       cout << left << setfill ('%') << setw (7) << dec << 127 << endl;//127%%%%

       cout << showbase << oct << 127 << endl;//0177

       cout << hex << 127 << endl;//0x7f

       cout << dec << 127 << endl;//127

       cout << noshowbase << oct << 127 << endl;//177

       cout << dec << 127 << endl;//127

       cout << 12.00 << endl;//12

       cout << setprecision (10) << showpoint << 12.00 << endl;//12.00000000

       cout.setf (ios::showpoint);//顯示後面的0

       cout << 12.00 << endl;//12.00000000

       cout.precision (4);

       cout << sqrt (200) << endl;//14.14

       cout.setf (ios::scientific);/*精度所限制的實際上只是底數小數部分的顯示位數*/

       cout << sqrt (200) << endl;//1.4142e+001

       ifstream ifs ("ex04.txt");

       ifs.unsetf (ios::skipws);/*跳過空白字符(空格符、製表符以及換行 符等),

       但如果出於某種原因,我們不希望忽略輸入流中的空白字符,

       那麼我們就可以使用控制符noskipws或者調用輸入流的unsetf(ios::skipws)成員函數。

       我們也可以使用操縱子skipws來取消noskipws的效果,或者調

       用輸入流的setf(ios::skipws)成員函數達到同樣的目的*/

       char c;

       while (ifs >> c)

       cout << c;

       return 0;

   }

10.字符串流:

   (1)ostringstream對象的一個優點是,可以利用輸出操作符“<<”的格式化能力把數值類型的數據轉換爲它們的字符串表示形式

   (2)另外:格式化字符數組

   char s[1024];

   sprintf (s, "money = %.2f\n", 23.44);


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