iostream與iostream.h的區別

c++的標準類庫被修訂了兩次,有兩個標準 c92和c99 這兩個庫現在都在並行使用,用 .h 包含的是c92 ,不帶 .h 的是c99的頭文件,對於普通用戶來說這兩者沒有什麼區別,區別是在內部函數的具體實現上。舊的c++頭文件是官方明確反對使用的,但舊的c頭文件則沒有(以保持對c的兼容性)。據說從 visual c++ .net 2003 開始,移除了舊的 iostream 庫。其實編譯器製造商不會停止對客戶現有軟件提供支持,所以在可以預計的將來,舊的c++頭文件還會囂張一段時間。如果能明白字符串頭文件的使用,舉一反三,其他的也差不多會用了:
 < string.h> 是舊的c/c++頭文件,對應的是基於char的字符串處理函數;
 < string> 是包裝了std的c++頭文件,對應的是新的strng類;
 < cstring> 是對應舊的c頭文件的std版本。
  
     如果編譯器都同時支持<  iostream > 和<  iostream.h > ,那使用#include <  iostream > ,得到的是置於名字空間std下的iostream庫的元素;如果使用#include <  iostream.h > ,得到的是置於全局空間的同樣的元素。在全局空間獲取元素會導致名字衝突,而設計名字空間的初衷正是用來避免這種名字衝突的發生。  

 

 
 想象訊雷下載軟件一樣,先從服務器確定下載文件的大小,初始時即保存文件,全部填充0, 
 多個線程下載數據直接寫入文件, 對自己線程負責下載的那段文件片的0進行改寫,
 其中就涉及到文件共享寫的操作

 
 出現的問題時:
 vc7.1< fstream>  已經不支持 filebuf::sh_read等關鍵字,不知在vc7下若要用文件流來對文件進行非獨佔讀和寫操作該如何實現?

 而:
 vc6.0中的iostream.h < fstream.h> 
 filebuf::sh_read
 filebuf::sh_write
 filebuf::sh_note
 filebuf::sh_openprot 

 無論自己是用vc6或者vc7的ide
 當用到標準的輸入輸出和文件流時都是:
 include< iostream> 
 include< fstream> 
 using namespace std    

 
 有兩種用法:
 a:
 include< iostream.h> 
 include< fstream.h> 

 b:
 include< iostream> 
 include< fstream> 

 a是標準用法,b是老式用法。   
   如果用了< iostream> ,則一定要引入命名空間,即" using   namespace   std " .   
   如果用了< iostream.h> ,則不那引入命名空間,否則會引起編譯錯誤,提示   
   找不到命名空間,例程如下:   
   //情況一:使用< iostream> 和命名空間   
   #include   < iostream>    
   using   namespace   std    
   int   main()   
   {   
   cout< < " < iostream>    need   to   use   namespace   std!/n"     
   return   0    
   }   
   輸出:   
   < iostream>    need   to   use   namespace   std!   
   press   any   key   to   continue   
     
   //情況二:使用< iostream.h> ,不引入命名空間   
   #include   < iostream.h>    
   //using   namespace   std    
   int   main()   
   {   
   cout< < " < iostream>    need   to   use   namespace   std!/n"     
   return   0    
   }   
   輸出:   
   < iostream>    need   to   use   namespace   std!   
   press   any   key   to   continue   
     
   //情況三:使用< iostream.h> ,引入命名空間,這時候編譯出錯   
   #include   < iostream.h>    
   using   namespace   std    
   int   main()   
   {   
   cout< < " < iostream>    need   to   use   namespace   std!/n"     
   return   0    
   }   
   編譯錯誤信息:   
   error   c2871:   ' std'    :   does   not   exist   or   is   not   a   namespace    

 從 visual c++ .net 2003 開始,移除了舊的 iostream 庫。
 標準 c++ 庫和以前的運行時庫之間的主要差異在於 iostream 庫。iostream 實現的具體細節已經更改,如果想鏈接標準 c++ 庫,可能有必要重寫代碼中使用 iostream 的部分。
 必須移除任何包含在代碼中的舊 iostream 頭文件(fstream.h、iomanip.h、ios.h、iostream.h、istream.h、ostream.h、streamb.h 和 strstrea.h),並添加一個或多個新的標準 c++ iostream 頭文件(< fstream> 、< iomanip> 、< ios> 、< iosfwd> 、< iostream> 、< istream> 、< ostream> 、< sstream> 、< streambuf>  和 < strstream> ,所有頭文件都沒有 .h 擴展名)。
 下表描述新的標準 c++ iostream 庫不同於舊 iostream 庫的行爲。
 在新的標準 c++ iostream 庫中: 
 open 函數不採用第三個參數(保護參數)。 
 無法從文件句柄創建流。 
 除了幾個例外,新的標準 c++ 庫中的所有名稱都在 std 命名空間中。有關更多信息,請參見使用 c++ 庫頭。 
 單獨用 ios::out 標誌無法打開 ofstream 對象。ios::out 標誌必須在邏輯 or 中和另一個 ios 枚舉數組合;比如,和 ios::in 或 ios::app 組合。 
 因爲設置了 eofbit 狀態,到達文件尾後 ios::good 不再返回非零值。 
 除非知道當前沒有設置基標誌,否則 ios::setf(_iflags) 不應和 ios::dec、ios::oct 或 ios::hex 的標誌值一起使用。格式化的輸入/輸出函數和運算符假定只設置了一個基。改用 ios_base。例如,setf( ios_base::oct  ios_base::basefield ) 清除所有基信息並將基設置成八進制。 
 ios::unsetf 返回 void 而不是以前的值。 
 若出現錯誤,istream::get( char&  _rch ) 不分配給 rch。 
 istream::get( char _pch  int _ncount  char _delim ) 有三點不同: 
 沒讀取任何內容時設置 failbit。 
 提取的字符後總是存儲一個 eos(與結果無關)。 
 值爲 -1 時 _ncount 是一個錯誤。 
 具有無效參數的 istream::seekg 不設置 failbit。 
 返回類型 streampos 是具有重載運算符的類。在返回 streampos 值(比如 istream::tellg、ostream::tellp、strstreambuf::seekoff 和 strstreambuf::seekpos)的函數中,應將返回值轉換成所需的類型:streamoff、fpos_t 或 mbstate_t。 
 strstreambuf::strstreambuf( _falloc  _ffree ) 中的第一個函數參數採用 size_t 參數而不是 long。 
 除了上述改動外,以下作爲舊 iostream 庫元素的函數、常數和枚舉數不是新 iostream 庫的元素: 
 filebuf、fstream ifstream 和 ofstream 的 attach 成員函數 
 filebuf、fstream ifstream 和 ofstream 的 fd 成員函數 
 filebuf::openprot 
 filebuf::setmode 
 ios::bitalloc 
 ios::nocreate 
 ios::noreplace 
 ios::sync_with_stdio 
 streambuf::out_waiting 
 streambuf::setbuf(相同的行爲使用 rdbuf ->  pubsetbuf)

 
 stl faq 上有對標準庫用法的一些建議,在《軟件研發》雜誌上也有這方面的討論的文章,可惜,這麼好的雜誌也停刊了(可能上面的知識對中國的程序員太過超前了,別人說的,奇怪,我怎麼看得明白了).

 what' s the difference between < xxx>  and < xxx.h>  headers

 the headers in iso standard c++ don' t have a .h suffix. this is something the standards committee changed from former practice. the details are different between headers that existed in c and those that are specific to c++. 

 the c++ standard library is guaranteed to have 18 standard headers from the c language. these headers come in two standard flavors  < cxxx>  and < xxx.h>  (where xxx is the basename of the header  such as stdio  stdlib  etc). these two flavors are identical except the < cxxx>  versions provide their declarations in the std namespace only  and the< xxx.h>  versions make them available both in std namespace and in the global namespace. the committee did it this way so that existing c code could continue to be compiled in c++. however the < xxx.h>  versions are deprecated  meaning they are standard now but might not be part of the standard in future revisions. (see clause d.5 of the iso c++ standard.) 

 the c++ standard library is also guaranteed to have 32 additional standard headers that have no direct counterparts in c  such as < iostream>   < string>   and < new> . you may see things like #include < iostream.h>  and so on in old code  and some compiler vendors offer .h versions for that reason. but be careful: the .h versions  if available  may differ from the standard versions. and if you compile some units of a program with  for example  < iostream>  and others with < iostream.h>   the program may not work. 

 for new projects  use only the< xxx>  headers  not the< xxx.h>  headers. 

 when modifying or extending existing code that uses the old header names  you should probably follow the practice in that code unless there' s some important reason to switch to the standard headers (such as a facility available in standard< iostream>  that was not available in the vendor' s < iostream.h> ). if you need to standardize existing code  make sure to change all c++ headers in all program units including external libraries that get linked in to the final  utable. 

 all of this affects the standard headers only. you' re free to name your own headers anything you like  see [27.9]. 

 標準庫擴展了原庫,例如新庫< string>   還支持寬字符集的操作 所以我認爲在現在大多數的編譯器都已支持標準c++的情況下,所有的程序都應該使用標準頭文件的導入方式!

 對於名字空間 namespace std 的使用,c++ 的 faq 的回答是這樣的

 should i use using namespace std in my code?

 probably not. 

 people don' t like typing std:: over and over  and they discover that using namespace std lets the compiler see any std name  even if unqualified. the fly in that ointment is that it lets the compiler see any std name  even the ones you didn' t think about. in other words  it can create name conflicts and ambiguities. 

 for example  suppose your code is counting things and you happen to use a variable or function named count. but the std library also uses the name count (it' s one of the std algorithms)  which could cause ambiguities. 

 look  the whole point of namespaces is to prevent namespace collisions between two independently developed piles of code. the using-directive (that' s the technical name for using namespace xyz) effectively dumps one namespace into another  which can subvert that goal. the using-directive exists for legacy c++ code and to ease the transition to namespaces  but you probably shouldn' t use it on a regular basis  at least not in your new c++ code. 

 if you really want to avoid typing std::  then you can either use something else called a using-declaration  or get over it and just type std:: (the un-solution): 

 use a using-declaration  which brings in specific  selected names. for example  to allow your code to use the name cout without a std:: qualifier  you could insert using std::cout into your code. this is unlikely to cause confusion or ambiguity because the names you bring in are explicit.

 just type std:: (the un-solution): 
  #include < vector> 
  #include < iostream> 
  
  void f(const std::vector< double> &  v)
  {
    using std::cout   // ← a using-declaration that lets you use cout without qualification
  
    cout < <  " values:"  
    for (std::vector< double> ::const_iterator p = v.begin()  p != v.end()  ++p)
      cout < <  '  '  < <  p 
    cout < <  ' /n'  
  }

 get over it and 

  #include < vector> 
  #include < iostream> 
  
  void f(const std::vector< double> &  v)
  {
    std::cout < <  " values:"  
    for (std::vector< double> ::const_iterator p = v.begin()  p != v.end()  ++p)
      std::cout < <  '  '  < <  p 
    std::cout < <  ' /n'  
  }

 i personally find it' s faster to type " std::"  than to decide  for each distinct std name  whether
 or not to include a using-declaration and if so  to find the best scope and add it there. but
 either way is fine. just remember that you are part of a team  so make sure you use an approach 
 that is consistent with the rest of your organization.

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