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 executable.
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.
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';
}
新聞熱點
疑難解答
圖片精選