C++中的iostream/iostream.h以及string/cstring/string.h/CString

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 >,得到的是置于全局空间的同样的元素。在全局空间获取元素会导致名字冲突,而设计名字空间的初衷正是用来避免这种名字冲突的发生。 


出现的问题时:
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   


标准 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 库中: 

  1. open 函数不采用第三个参数(保护参数)。 
  2. 无法从文件句柄创建流 
  3. 除了几个例外,新的标准 C++ 库中的所有名称都在 std 命名空间中。有关更多信息,请参见使用 C++ 库头。 
  4. 单独用 ios::out 标志无法打开 ofstream 对象。ios::out 标志必须在逻辑 OR 中和另一个 ios 枚举数组合;比如,和 ios::in 或 ios::app 组合。 
  5. 因为设置了 eofbit 状态,到达文件尾后 ios::good 不再返回非零值。 
  6. 除非知道当前没有设置基标志,否则 ios::setf(_IFlags) 不应和 ios::dec、ios::oct 或 ios::hex 的标志值一起使用。格式化的输入/输出函数和运算符假定只设置了一个基。改用 ios_base。例如,setf( ios_base::oct, ios_base::basefield ) 清除所有基信息并将基设置成八进制。 
  7. ios::unsetf 返回 void 而不是以前的值。 
  8. 若出现错误,istream::get( char& _Rch ) 不分配给 Rch。 
  9. istream::get( char* _Pch, int _Ncount, char _Delim ) 有三点不同: 
  10. 没读取任何内容时设置 failbit。 
  11. 提取的字符后总是存储一个 eos(与结果无关)。 
  12. 值为 -1 时 _Ncount 是一个错误。 
  13. 具有无效参数的 istream::seekg 不设置 failbit。 
  14. 返回类型 streampos 是具有重载运算符的类。在返回 streampos 值(比如 istream::tellg、ostream::tellp、strstreambuf::seekoff 和 strstreambuf::seekpos)的函数中,应将返回值转换成所需的类型:streamoff、fpos_t 或 mbstate_t。 
  15. strstreambuf::strstreambuf( _Falloc, _Ffree ) 中的第一个函数参数采用 size_t 参数而不是 long。 
除了上述改动外,以下作为旧 iostream 库元素的函数、常数和枚举数不是新 iostream 库的元素: 
  1. filebuf、fstream ifstream 和 ofstream 的 attach 成员函数 
  2. filebuf、fstream ifstream 和 ofstream 的 fd 成员函数 
  3. filebuf::openprot 
  4. filebuf::setmode 
  5. ios::bitalloc 
  6. ios::nocreate 
  7. ios::noreplace 
  8. ios::sync_with_stdio 
  9. streambuf::out_waiting 
  10. streambuf::setbuf(相同的行为使用 rdbuf -> pubsetbuf)

CString/string/string.h

<string.h>

<string.h>是C版本的头文件,包含比如strcpy、strcat之类的字符串处理函数。string.h中不包含“string”这个数据类型只有一些常用字符串处理函数。如果试图使用string定义变量,会出现“string”未定义的错误。在使用string.h时不需要使用命名空间。

#include <string.h>
using namespace std;
class CSimpleClass  
{
public:
	void InitConst();
	CSimpleClass(int i);
	virtual ~CSimpleClass();
	const int m_cstI;
	string strSample;                    //error!string未定义
};

<cstring>

在C++标准化(1998年)过程中,为了兼容以前,标准化组织将所有这些文件都进行了新的定义,加入到了标准库中,加入后的文件名就新增了一个"c"前缀并且去掉了.h的后缀名,所以string.h头文件成了cstring头文件。但是其实现却是相同的或是兼容以前的,这就是<cstring>的来源,不要觉得又多了一个东西。相当于标准库组织给它盖了个章,说“你也是我的标准程序库的一份子了”。cstring.h中同样不包含“string”这个数据类型,如果试图使用string定义变量,会出现“string”未定义的错误。在使用cstring时需要使用命名空间。

#include <cstring>
using namespace std;
class CSimpleClass  
{
public:
	void InitConst();
	CSimpleClass(int i);
	virtual ~CSimpleClass();
	const int m_cstI;
	string strSample;                    //error!string未定义
};

<string>

<string>是C++标准定义的头文件,它定义了一个string的字符串类,里面包含了string类的各种操作,如s.size(), s.erase(), s.insert()等。但<string>又包含了老的C版本的字符串操作如strcpy、strcat等,这就相当于,在<string>的文件中除了定义自己的string类之外,还加了一个#include<string.h>一句包含了C版本的字符串操作。故包含string时需要使用命名空间,并且可以使用数据类型string定义变量。

#include <string>
using namespace std;
class CSimpleClass  
{
public:
	void InitConst();
	CSimpleClass(int i);
	virtual ~CSimpleClass();
	const int m_cstI;
	string strSample;                    //正确
};


<CString>

 在MFC中,还有CString类,它与cstring是有本质区别的,前者是类名,使用时包含头文件afx.h,后者是文件名,两者实现的方法也大相径庭。

CString应该包含的头文件:<atlstr.h>(控制台)或<afxstr.h>(MFC),一般在使用MFC As Shared Dll之后不需要包含

1、<atlstr.h>

非MFC版本,控制台程序就用这个

<afx.h><afxcoll.h>都可以。//要项目->属性->常规里设置为使用MFC(动/静).

2、<afxstr.h>// only be used in MFC projects.

MFC版本,需要链接MFC的dll或静态库。网上很多人说要包含<afx.h>,<afx.h>包含的东西就比较多了CObject及其派生类,还有文件类、时间类、异常类、字符串类等等(700多行的位置包含了afxstr.h),如果仅仅需要cstring的话,包含<afxstr.h>就够了。


 

 
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值