前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >string、string.h和ctring学习小结

string、string.h和ctring学习小结

作者头像
阳光岛主
发布2019-02-19 17:54:47
9990
发布2019-02-19 17:54:47
举报
文章被收录于专栏:米扑专栏米扑专栏米扑专栏

string 和 string.h (和cstring等价)头文件的区别

为什么下面这段代码  #include <string.h>  void main()  {      string aaa= "abcsd d";      printf("looking for abc from abcdecd %s/n",          (strcmp(aaa,"abc")) ? "Found" : "Not Found");  }  不能正确执行,说是string类型没有定义  而下面:  #include <string>  using namespace std;  void main()  {      string aaa= "abcsd d";      printf("looking for abc from abcdecd %s/n",          (strcmp(aaa,"abc")) ? "Found" : "Not Found");  }  这里的string编译器就认识了,但是strcmp就不认识了呢?  ---------------------------------------------------------------  一般一个C++的老的带“.h”扩展名的库文件,比如iostream.h,在新标准后的标准库中都有一个不带“.h”扩展名的相对应,区别除了后者的好多改进之外,还有一点就是后者的东东都塞进了“std”名字空间中。  但唯独string特别。  问题在于C++要兼容C的标准库,而C的标准库里碰巧也已经有一个名字叫做“string.h”的头文件,包含一些常用的C字符串处理函数,比如楼主提到的strcmp。  这个头文件跟C++的string类半点关系也没有,所以<string>并非<string.h>的“升级版本”,他们是毫无关系的两个头文件。  要达到楼主的目的,比如同时:  #include <string.h>  #include <string>  using namespace std;  或者  #include <cstring>  #include <string>  其中<cstring>是与C标准库的<string.h>相对应,但裹有std名字空间的版本。

=======================================================================

CString,是ATL/MFC共享的, string是C++标准库的

         相同点:

(1)用他们都可以取代对char*的使用。

(2)都封装了有丰富的字符串操作接口。

(3)他们都是C++的类库。--

以string的使用为例,不能有如下用法:

     string * pstr = NULL;              //定义一个指向字符串的指针

     pstr->append("Hello world.");      //在该字符串的末尾粘接上另一个字符。

这样做编译器不会有任何警告和错误,但是运行 的时候就会有异常。

原因是没有理解string是一个类,而在定义类的对象的时候是需要调用其构造函数的。上面 既没有调用string的构造函数,而且还把指针赋值为NULL,很明显调用该类的对象的接口的时候会出错。但是编译器却发现不了这个问题的。

正确的方法是如下:

/*这里必须要用c++的宏new,而不能用c中的malloc,原因是new不但会分配一 块内存,*/

/*还执行了类的构造函数。当然,string类的实例化还可以通过已有的某个string对象进行,请另查阅*/

string * pstr = new string("Hello world.");

pstr->append("Hello world.");

cout<<"string * pstr is:"<<*pstr<<endl;

或者不用指针,如下也可以:

string str;     //会自动调用默认的构造函数,构造一个string类的对象。

str.apend("Hello world.");

cout<<"string str is:"<<str<<endl;

(4)他们都使用了模板的技术。

不同之处:

(1)CString 类是微软的visual c++提供的MFC里面的一个类,所以只有支持MFC的工程才可以使用。如在linux上的工程就不能用CString了,只能用标准C++中的 string类了。另外,因为string类是在c++标准库中,所以它被封装在了std命名空间中,使用之前需要声明using namespace std;而CString类并不在std命名空间中,因为它不是c++的标准库,只是微软的一个封装库。这点看来用string类的程序的移植性更好。

(2)string类既是一个标准c++的类 库,同时也是STL(Standard Template Library,标准模版库)中的类库,所以支持Iterator操作。

(3)CString类和string类提供 的方法接口并不完全相同,所以不要糊里糊涂的认为某个类中怎么没有另外一个类中的方法啊。:-)。。

(4)他们和char*之间的转换方法也不一 样。

string类型的变量如果要转换成char*类型字符串,string类中提供了三个方法 如下:

const charT* c_str() const //c_str 直接返回一个以/0结尾的字符串。 const charT* data() const //data 直接以数组方式返回string的内容,其大小为size()的返回值,结尾并没有/0字符size_type copy(charT* buf, size_type n, size_type pos = 0) const //copy 把string的内容拷贝到buf空间中。

注意:c_str()的返回类型是指向常量charT类型的指针,说明指针所指空间的内容不 允许修改,只可以读取不可以更改。c_str()返回的指针

是string内部的指针,并没有像copy函数一样把其内容拷贝出来。这可以从下面例子中 看出来:

string * pstr = new string("Hello world.");

const char * ptmp = pstr->c_str(); //并没有通过malloc或者new为指针ptmp分配内存,只是把string中的数据指针赋给了ptmp而已

cout<<"Get the string->cstr is:"<<ptmp<<endl; //正确的输出了Hello world.

但是如果用copy方法时必须如下方法:

char * p = (char *)malloc(100*sizeof(char)); //必须为指针p分配内存空间用于存放从string里拷贝出来的数据

pstr->copy(p,pstr->length(),0); //如果没有上面分配内存空间,这个语句在运行时就会报段错误。

cout<<"char * p:copy from string is:"<<p<<endl; //正确的输出了字符串Hello world

CString类型字符串对象转换成char*字符串比较麻烦一点,方法也有3种:

今天遇到一个难题,以前一直都是从TCHAR *转换到CString,今天需要CString 转换成TCHAR *的方法,找了一下MSDN文档,没有发现有现成的函数可以用。后来上网搜索了一下,方法还不少。如下几种:

方法一,使用强制转换。例如:

CString theString( "This is a test" );

LPTSTR lpsz =(LPTSTR)(LPCTSTR)theString;

  方法二,使用strcpy。例如:

CString theString( "This is a test" );

LPTSTR lpsz = new TCHAR[theString.GetLength()+1];

_tcscpy(lpsz, theString);

  需要说明的是,strcpy(或可移值Unicode/MBCS的_tcscpy)的第 二个参数是 const wchar_t* (Unicode)或const char* (ANSI),系统编译器将会自动对其进行转换。

  方法三,使用CString::GetBuffer。例如:

CString s(_T("This is a test "));

LPTSTR p = s.GetBuffer();

// 在这里添加使用p的代码

if(p != NULL) *p = _T('/0');

s.ReleaseBuffer();

// 使用完后及时释放,以便能使用其它的CString成员函数

-------------------------------------------------------------------

我尝试了后面两种,都能成功,最后我还是选用了简单的第二种方法,因为采用第三种方法的话, 需要用GetBuffer();函数,而该函数的使用需要非常的小心谨慎。

源码如下:

/**********

检查输入的手机型号是否合法。规定手机型号以CoolPad_开始。合法则返回TRUE,否 则返回FALSE

***********/

BOOL CAutoBuildConfigDlg::CheckMobileName(CString strMobileName)

{

wchar_t * pdest;

CString strMobileName_temp;

strMobileName_temp = strMobileName;

TCHAR strCOOLPAD[] = L"COOLPAD_";

LPTSTR lpsz = new TCHAR[strMobileName_temp.GetLength()+1];

wcsncpy_s(lpsz,(strMobileName_temp.GetLength()+1),strMobileName_temp, (strMobileName_temp.GetLength()+1));

errno_t err;

err = _wcsupr_s(lpsz,strMobileName_temp.GetLength()+1);//因为没有找到不区分大小写的查找子字符串的函 数,所以决定转换成大写然后进行比较。

pdest = wcsstr( lpsz,strCOOLPAD );

if( pdest != NULL )

{

    return TRUE;

}

else

{

   return FALSE;

}

}

CString/string 区别及其转化 利用MFC进行编程时,我们从对话框中利用GetWindowText得到的字符串是CString类型,CString是属于MFC的类。而一些标准 C/C++库函数是不能直接对CString类型进行操作的,所以我们经常遇到将CString类型转化char*等等其他数据类型的情况。这里总结备忘 于此! 首先要明确,标准C中是不存在string类型的,string是标准C++扩充字符串操作的一个类。但是我们知道标准C中有string.h这个头文 件,这里要区分清楚,此string非彼string。string.h这个头文件中定义了一些我们经常用到的操作字符串的函数,如:strcpy、 strcat、strcmp等等,但是这些函数的操作对象都是char*指向的字符串。 而C++的string类操作对象是string类型字符串,该类重装了一些运算符,添加了一些字符串操作成员函数,使得操作字符串更加方便。有的时候我 们要将string串和char*串配合使用,所以也会涉及到这两个类型的转化问题。

1.CString和string的转化 stringstr="ksarea"; CStringcstr(str.c_str());//或者CString cstr(str.data());初始化时才行 cstr=str.c_str();或者cstr=str.data(); str=cstr.GetBuffer(0); //CString -> string cstr.format("%s", str.c_str()); //string->CString cstr.format("%s", str.data()); //string->CString str = LPCSTR(cstr); //CString->string /*c_str()和data()区别是:前者返回带'/0'的字符串,后者则返回不带'/0'的字符串*/ 2.CString和int的转换 inti=123; CStringstr; str.format("%d",i);//int->CString 其他的基本类型转化类似 i=atoi(str);//CString->int 还有(atof,atol) 3.char*和CString的转换 CStringcstr="ksarea"; char* ptemp=cstr.getbuffer(0); char* str; strcpy(str,ptemp);//CString->char* cstr.releasebuffer(-1);

char*str="lovesha"; CStringcstr=str;//char*->CString string类型不能直接赋值给CString

至于int与float、string与char*之间的转化可以使用强制转化,或者标准库函数进行。对于CString与其他类型的转化方法很多,但其 实都殊途同归,朝着一个方向即将类型首先转化为char*类型,因为char*是不同类型之间的桥梁。得到char*类型,转化为其他类型就非常容易了。

CString,如果项目用的是unicode的话那么实际上是CStringW类型,这个时候向string转换的时候,编译器会报 错,const char* 无法转换为const w_char *,这个时候只能这个做了。

1 //tmp1极为CStringW宽字符变量 2 //转换为psText的char* 变量了 3  4 #ifdef UNICODE 5              DWORD dwNum = WideCharToMultiByte(CP_OEMCP, NULL, tmp1.GetBuffer(0), -1, NULL, 0, NULL, FALSE); 6              char *psText; 7              psText = new char[dwNum]; 8              if (!psText) 9                  delete []psText; 10              WideCharToMultiByte(CP_OEMCP, NULL, tmp1.GetBuffer(0), -1, psText, dwNum, NULL, FALSE); 11 #endif
要添加宏定义
如果要char*转换为CString。直接赋值就可以了。因为已经重载了CString =号
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2010年10月01日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档