关于CString总结

CString 的内存结构和初始化 WTL :: CString 包含在 WTL 头文件 atlmisc.h 中,并且在未定义宏 _WTL_NO_CSTRING 时可用。WTL :: CString 是一个非常独立的类,内存结构与 BSTR 类似,即有一个额外的字符串信息头标识字符串相关信息,信息头后紧跟有效字符串数据。此外它还借鉴 COM ,使用引用计数管理字符串对象指针的复制和对象的析构,使得对字符串对象的复制只是复制指针而引用相同内存区的有效字符串数据。这样提高了内存利用率和操作的高效性。引用计数也管理对象的生命期,使其超出生命期没有被 阅读详情
 前言:串操作是编程中最常用也最基本的操作之一。 做为VC程序员,无论是菜鸟或高手都曾用过Cstring。而且好像实际编程中很难离得开它(虽然它不是标准C++中的库)。因为MFC中提供的这个类对我们操作字串实在太方便了,CString不仅提供各种丰富的操作函数、操作符重载,使我们使用起串起来更象basic中那样直观;而且它还提供了动态内存分配,使我们减少了多少字符串数组越界的隐患。但是,我们在使用过程中也体会到CString简直太容易出错了,而且有的不可捉摸。所以有许多高人站过来,建议抛弃它。

在此,我个人认为:CString封装得确实很完美,它有许多优点,如“容易使用 ,功能强,动态分配内存,大量进行拷贝时它很能节省内存资源并且执行效率高,与标准C完全兼容,同时支持多字节与宽字节,由于有异常机制所以使用它安全方便” 其实,使用过程中之所以容易出错,那是因为我们对它了解得还不够,特别是它的实现机制。因为我们中的大多数人,在工作中并不那么爱深入地去看关于它的文档,何况它还是英文的。

由于前几天我在工作中遇到了一个本不是问题但却特别棘手、特别难解决而且莫名惊诧的问题。好来最后发现是由于CString引发的。所以没办法,我把整个CString的实现全部看了一遍,才慌然大悟,并彻底弄清了问题的原因(这个问题,我已在csdn上开贴)。在此,我想把我的一些关于CString的知识总结一番,以供他(她)人借鉴,也许其中有我理解上的错误,望发现者能通知我,不胜感谢。

 

1. CString实现的机制.

   CString是通过“引用”来管理串的,“引用”这个词我相信大家并不陌生,象Window内核对象、COM对象等都是通过引用来实现的。而CString也是通过这样的机制来管理分配的内存块。实际上CString对象只有一个指针成员变量,所以任何CString实例的长度只有4字节.

       即: int len = sizeof(CString);//len等于4

这个指针指向一个相关的引用内存块,如图: CString str("abcd");

 

 

 

 

 

‘A’

‘B’

‘C’

‘D’

0

                                           

                              

                            

     0x04040404                           head部,为引用内存块相关信息

                                                                   

         str                               0x40404040

                                           

                                          

                                          

                                          

 

正因为如此,一个这样的内存块可被多个CString所引用,例如下列代码:

CString str("abcd");

CString a = str;

CString b(str);

CString c;

c = b;

上面代码的结果是:上面四个对象(str,a,b,c)中的成员变量指针有相同的值,都为0x40404040.而这块内存块怎么知道有多少个CString引用它呢?同样,它也会记录一些信息。如被引用数,串长度,分配内存长度。

这块引用内存块的结构定义如下:

struct CStringData

{

  long nRefs;       //表示有多少个CString 引用它. 4

  int nDataLength;  //串实际长度. 4

  int nAllocLength; //总共分配的内存长度(不计这头部的12字节). 4

};

由于有了这些信息,CString就能正确地分配、管理、释放引用内存块。

如果你想在调试程序的时候获得这些信息。可以在Watch窗口键入下列表达式:

(CStringData*)((CStringData*)(this->m_pchData)-1)或

(CStringData*)((CStringData*)(str.m_pchData)-1)//str为指CString实例

 

正因为采用了这样的好机制,使得CString在大量拷贝时,不仅效率高,而且分配内存少。

 

 

2.LPCTSTR 与 GetBuffer(int nMinBufLength)

这两个函数提供了与标准C的兼容转换。在实际中使用频率很高,但却是最容易出错的地方。这两个函数实际上返回的都是指针,但它们有何区别呢?以及调用它们后,幕后是做了怎样的处理过程呢?

  (1) LPCTSTR 它的执行过程其实很简单,只是返回引用内存块的串地址。 它是作为操作符重载提供的,所以在代码中有时可以隐式转换,而有时却需强制转制。如:

          CString str;

          const char* p = (LPCTSTR)str;

          //假设有这样的一个函数,Test(const char* p);  你就可以这样调用

          Test(str);//这里会隐式转换为LPCTSTR

  (2) GetBuffer(int nMinBufLength) 它类似,也会返回一个指针,不过它有点差别,返回的是LPTSTR

  (3) 这两者到底有何不同呢?我想告诉大家,其本质上完全不一样,一般说LPCTSTR转换后只应该当常量使用,或者做函数的入参;而GetBuffer(...)取出指针后,可以通过这个指针来修改里面的内容,或者做函数的出参。为什么呢?也许经常有这样的代码:

        CString str("abcd");

        char* p = (char*)(const char*)str;

        p[2] = 'z';  

      其实,也许有这样的代码后,你的程序并没有错,而且程序也运行得挺好。但它却是非常危险的。再看

        CString str("abcd");

        CString test = str;

        ....

        char* p = (char*)(const char*)str;

        p[2] = 'z';  

        strcpy(p, "akfjaksjfakfakfakj");//这下完蛋了  

      你知道此时,test中的值是多少吗?答案是"abzd"。它也跟着改变了,这不是你所期望发生的。但为什么会这样呢?你稍微想想就会明白,前面说过,因为CString是指向引用块的,str与test指向同一块地方,当你p[2]='z'后,当然test也会随着改变。所以用它做LPCTSTR做转换后,你只能去读这块数据,千万别去改变它的内容。

     

假如我想直接通过指针去修改数据的话,那怎样办呢?就是用GetBuffer(...).看下述代码:

        CString str("abcd");

        CString test = str;

        ....

        char* p = str.GetBuffer(20);

        p[2] = 'z';  //   执行到此,现在test中值却仍是"abcd"

        strcpy(p, "akfjaksjfakfakfakj");   //    执行到此,现在test中值还是"abcd"

为什么会这样?其实GetBuffer(20)调用时,它实际上另外建立了一块新内块存,并分配20字节长度的buffer,而原来的内存块引用计数也相应减1.  所以执行代码后str与test是指向了两块不同的地方,所以相安无事。

(4) 不过这里还有一点注意事项:就是str.GetBuffer(20)后,str的分配长度为20,即指针p它所指向的buffer只有20字节长,给它赋值时,切不可超过,否则灾难离你不远了;如果指定长度小于原来串长度,如GetBuffer(1),实际上它会分配4个字节长度(即原来串长度);另外,当调用GetBuffer(...)后并改变其内容,一定要记得调用ReleaseBuffer(),这个函数会根据串内容来更新引用内存块的头部信息。

   (5) 最后还有一注意事项,看下述代码:

      char* p = NULL;

      const char* q = NULL;

      {

          CString str = "abcd";

          q = (LPCTSTR)str;

          p = str.GetBuffer(20);

          AfxMessageBox(q);// 合法的

          strcpy(p, "this is test");//合法的,

      }

      AfxMessageBox(q);// 非法的,可能完蛋

      strcpy(p, "this is test");//非法的,可能完蛋

     这里要说的就是,当返回这些指针后, 如果CString对象生命结束,这些指针也相应无效。

 

3.拷贝 & 赋值 & "引用内存块" 什么时候释放?

 

  下面演示一段代码执行过程

   void Test()

   {

CString str("abcd");

//str指向一引用内存块(引用内存块的引用计数为1,长度为4,分配长度为4)

CString a;

//a指向一初始数据状态,

a = str;

//a与str指向同一引用内存块(引用内存块的引用计数为2,长度为4,分配长度为4)

CString b(a);

//a、b与str指向同一引用内存块(引用内存块的引用计数为3,长度为4,分配长度为4)

     {

        LPCTSTR temp = (LPCTSTR)a;

//temp指向引用内存块的串首地址。(引用内存块的引用计数为3,长度为4,分配长度为4)

        CString d = a;

//a、b、d与str指向同一引用内存块(引用内存块的引用计数为4,                                长度为4,分配长度为4)

        b = "testa";

//这条语句实际是调用CString::operator=(CString&)函数。                    b指向一新分配的引用内存块。(新分配的引用内存块的                       引用计数为1, 长度为5, 分配长度为5)

//同时原引用内存块引用计数减1. a、d与str仍指向原                      引用内存块(引用内存块的引用计数为3,长度为4,分配长度为4)                    

}

//由于d生命结束,调用析构函数,导至引用计数减1(引用内存块的引用计数为2,长度为4,分配长度为4)

LPTSTR temp = a.GetBuffer(10);

//此语句也会导致重新分配新内存块。temp指向新分配引用内存块的串首地址(新                                   分配的引用内存块的引用计数为1,长度为0,分配长度为10)

//同时原引用内存块引用计数减1.  只有str仍                                     指向原引用内存块 (引用内存块的引用计数为1,                                     长度为4, 分配长度为4)                     

strcpy(temp, "temp");

//a指向的引用内存块的引用计数为1,长度为0,分配长度为10 a.ReleaseBuffer();//注意:a指向的引用内存块的引用计数为1,长度为4,分配长度为10

   }

   //执行到此,所有的局部变量生命周期都已结束。对象str a b 各自调用自己的析构构

   //函数,所指向的引用内存块也相应减1

   //注意,str a b 所分别指向的引用内存块的计数均为0,这导致所分配的内存块释放

  

    通过观察上面执行过程,我们会发现CString虽然可以多个对象指向同一引用内块存,但是它们在进行各种拷贝、赋值及改变串内容时,它的处理是很智能并且非常安全的,完全做到了互不干涉、互不影响。当然必须要求你的代码使用正确恰当,特别是实际使用中会有更复杂的情况,如做函数参数、引用、及有时需保存到CStringList当中,如果哪怕有一小块地方使用不当,其结果也会导致发生不可预知的错误

 

5  FreeExtra()的作用

   看这段代码

   (1)   CString str("test");

   (2)   LPTSTR temp = str.GetBuffer(50);

   (3)   strcpy(temp, "there are 22 character");

   (4)   str.ReleaseBuffer();

   (5)   str.FreeExtra();

   上面代码执行到第(4)行时,大家都知道str指向的引用内存块计数为1,长度为22,分配长度为50. 那么执行str.FreeExtra()时,它会释放所分配的多余的内存。(引用内存块计数为1,长度为22,分配长度为22)

 

6  Format(...)  与 FormatV(...)

   这条语句在使用中是最容易出错的。因为它最富有技巧性,也相当灵活。在这里,我没打算对它细细分析,实际上sprintf(...)怎么用,它就怎么用。我只提醒使用时需注意一点:就是它的参数的特殊性,由于编译器在编译时并不能去校验格式串参数与对应的变元的类型及长度。所以你必须要注意,两者一定要对应上,

   否则就会出错。如:

   CString str;

   int a = 12;

   str.Format("first:%l, second: %s", a, "error");//result?试试

 

7  LockBuffer() 与 UnlockBuffer()

   顾名思议,这两个函数的作用就是对引用内存块进行加锁及解锁。但使用它有什么作用及执行过它后对CString串有什么实质上的影响。其实挺简单,看下面代码:

   (1)   CString str("test");

   (2)   str.LockBuffer();

   (3)   CString temp = str;

   (4)   str.UnlockBuffer();

   (5)   str.LockBuffer();

   (6)   str = "error";

   (7)   str.ReleaseBuffer();

   执行完(3)后,与通常情况下不同,temp与str并不指向同一引用内存块。你可以在watch窗口用这个表达式(CStringData*)((CStringData*)(str.m_pchData)-1)看看。

   其实在msdn中有说明:

        While in a locked state, the string is protected in two ways:

 

           No other string can get a reference to the data in the locked string, even if that string is assigned to the locked string.

           The locked string will never reference another string, even if that other string is copied to the locked string.

 

8  CString 只是处理串吗?

   不对,CString不只是能操作串,而且还能处理内存块数据。功能完善吧!看这段代码

       char  p[20];

       for(int loop=0; loop<sizeof(p); loop++)

       {

              p[loop] = 10-loop;

       }

       CString str((LPCTSTR)p, 20);

       char temp[20];

       memcpy(temp, str, str.GetLength());

    str完全能够转载内存块p到内存块temp中。所以能用CString来处理二进制数据

 

8  AllocSysString()与SetSysString(BSTR*)

   这两个函数提供了串与BSTR的转换。使用时须注意一点:当调用AllocSysString()后,须调用它SysFreeString(...)

 

9  参数的安全检验

   在MFC中提供了多个宏来进行参数的安全检查,如:ASSERT.  其中在CString中也不例外,有许多这样的参数检验,其实这也说明了代码的安全性高,可有时我们会发现这很烦,也导致Debug与Release版本不一样,如有时程序Debug通正常,而Release则程序崩溃;而有时恰相反,Debug不行,Release行。其实我个人认为,我们对CString的使用过程中,应力求代码质量高,不能在Debug版本中出现任何断言框,哪怕release运行似乎看起来一切正常。但很不安全。如下代码:

   (1)   CString str("test");

   (2)   str.LockBuffer();

   (3)   LPTSTR temp = str.GetBuffer(10);

   (4)   strcpy(temp, "error");

   (5)   str.ReleaseBuffer();

   (6)   str.ReleaseBuffer();//执行到此时,Debug版本会弹出错框

 

10 CString的异常处理

   我只想强调一点:只有分配内存时,才有可能导致抛出CMemoryException.

   同样,在msdn中的函数声明中,注有throw( CMemoryException)的函数都有重新分配或调整内存的可能。

 

11 跨模块时的Cstring。即一个DLL的接口函数中的参数为CString&时,它会发生怎样的现象。解答我遇到的问题。我的问题原来已经发贴,地址为:

http://www.youkuaiyun.com/expert/topic/741/741921.xml?temp=.2283136

 

  构造一个这样CString对象时,如CString str,你可知道此时的str所指向的引用内存块吗?也许你会认为它指向NULL。其实不对,如果这样的话,CString所采用的引用机制管理内存块就会有麻烦了,所以CString在构造一个空串的对象时,它会指向一个固定的初始化地址,这块数据的声明如下:

   AFX_STATIC_DATA int _afxInitData[] = {-1,0,0,0};

  简要描述概括一下:当某个CString对象串置空的话,如Empty(),CString a等,它的成员变量m_pchData就会指向_afxInitData这个变量的地址。当这个CString对象生命周期结束时,正常情况下它会去对所指向的引用内存块计数减1,如果引用计数为0(即没有任何CString引用它时),则释放这块引用内存。而现在的情况是如果CString所指向的引用内存块是初始化内存块时,则不会释放任何内存。

 

  说了这么多,这与我遇到的问题有什么关系呢?其实关系大着呢?其真正原因就是如果exe模块与dll模块有一个是static编译连接的话。那么这个CString初始化数据在exe模块与dll模块中有不同的地址,因为static连接则会在本模块中有一份源代码的拷贝。另外一种情况,如果两个模块都是share连接的,CString的实现代码则在另一个单独的dll中实现,而AFX_STATIC_DATA指定变量只装一次,所以两个模块中_afxInitData有相同的地址。

  现在问题完全明白了吧!你可以自己去演示一下。

  __declspec (dllexport) void test(CString& str)

  {

    str = "abdefakdfj";//如果是static连接,并且传入的str为空串的话,这里出错。

  }

 

最后一点想法:写得这里,其实CString中还有许多技巧性的好东东,我并没去解释。如很多重载的操作符、查找等。我认为还是详细看看msdn,这样也许会比我讲的好多了。我只侧重那些可能会出错的情况。当然,如我上面叙述中有错误,敬请高手指点,不胜感谢!

肿瘤基因组分析实战:VAF、MAF、CCF这些指标到底怎么算?(附Python代码示例) 本文通过Python代码示例,详细解析了肿瘤基因组分析中VAF、MAF和CCF三大核心指标的计算逻辑与应用。文章从VCF文件解析入手,逐步演示了变异等位基因频率、次等位基因频率及癌细胞分数的计算方法,并探讨了拷贝数变异对结果的影响及克隆结构推断的实战流程,为生物信息分析提供实用指南。 阅读详情

相关推荐

激光雷达-IMU标定工具lidar_imu_calib保姆级教程(VLP-16实测)

本文提供激光雷达与IMU联合标定的详细实战教程,重点解析lidar_imu_calib工具在VLP-16上的应用。从环境部署、数据采集技巧到参数配置与结果验证,手把手指导完成标定全流程,并详解如何在LIO-SAM等SLAM系统中应用标定结果,确保传感器融合精度。

food6的博客 475

CString的API简介

引子 因为MFC很难用,所以它的CString也很难用。但是吐槽归吐槽,实际项目中还是避免不了MFC,也就不得不了解CString。下面对CString的比较常用的API做些整理,方便以后查阅。 注意,使用CString必须包含“afx.h”头文件,但是使用VS创建MFC工程,也会默认自带的,勿需费神。 CString 类对象的初始化 CString str; CString str1...

ptrunner的专栏 835

全网最详细 解决戴维南定理的详细推导

替代定理,戴维南定理详细证明

m0_52555753的博客 3万+

自己的STRING类

#include #include using namespace std; class CSTRING { private: char *p; public: CSTRING(); CSTRING(const char a[]); CSTRING(CSTRING &a); ~CSTRING(){delete p;} CSTRING operator =(const CSTRING &am...

qq_43789349的博客 254

决策规划算法四:Piecewise Jerk Path Optimizer

一,问题分析 路径规划的本质目的:规划出一条安全(无碰撞),舒适(平滑),符合车辆运动学的轨迹。 如下图所示,决策算法开辟凸空间后,路径规划算法用数值优化的方法搜索出一条最优路径,即将问题转化为二次规划的问题,采用二次规划的求解器进行求解。 二次规划问题的求解顺序: 1,确定优化变量 2,确定目标函数 3,确定约束条件 4,将目标函数和约束条件变形为二次规划的标准形式 5,用二次规划求解器进行求解,获得优化变量的序列,使得目标函数取得最小值。 注:路径的最终表达式为:,..

肥嘟嘟的左卫门 8560

RTKLIB模糊度固定实战:三种模式对比与部分模糊度固定代码解析

本文深入解析RTKLIB中模糊度固定的三种核心模式(continuous、instantaneous、fix and hold),对比其性能与适用场景,并详细拆解了部分模糊度固定技术的源码实现。通过实战案例与代码级解析,为GNSS高精度定位开发者提供了在不同数据特性下提升固定成功率的优化思路与配置建议。

efc1234567的博客 471

c++下使用CString将字符串转二进制、八进制、十进制、十六进制

(1).转二进制 #include"afx.h" #include void main() { char c[5]="0101"; CString cs=_T(c); int last=_tcstol(c,NULL,2);//2表示二进制 printf("%d\n",last);//使用十进制输出结果为5 } (2).转八进制 #include"afx.h" #

lengxin337的专栏 5101

MOSFET高频响应实战:如何用LTspice仿真内部电容效应(附模型文件)

本文深入解析MOSFET高频响应中的内部电容效应,通过LTspice仿真工具详细展示如何提取模型参数并优化高频特性。从栅极相关电容到结电容的物理本质,再到实战案例中的开关损耗分析和频率响应扫描,提供全面的设计优化方法,帮助工程师有效应对高速开关电路中的电容挑战。

weixin_33725722的博客 390

CString类详细介绍

CString类背景介绍 这是本人第一次写csdn博客,如果有写得不好的地方请各位大佬帮忙指出不足之处,本人定会谦虚请教。众所周知,MFC(微软基础类库)是基于Windows界面开发的,它封装了大部分的Windows API(应用程序接口)函数,由C格式的函数升级为类库。而CString字符串类是MFC中比较常用的一个类,CString类里封装了很多对字符串操作的成员函数。接下来讲解该类的成员函数...

kevin685264的博客 9093

冲压机器人系列编程:ABB IRB 6700_(6).RAPID编程语言入门

主菜单:包含文件、编辑、视图、工具等常用操作。项目浏览器:显示当前项目的文件结构,包括机器人模型、程序模块等。图形界面:用于创建和编辑机器人的虚拟环境。RAPID代码编辑器:用于编写和编辑RAPID代码。仿真控制面板:用于控制仿真过程,包括启动、暂停、停止等。变量是存储数据的容器,可以通过变量名访问和修改其存储的数据。变量定义时需要指定其类型和名称。% 定义一个整数变量并赋初值% 定义一个实数变量,未赋初值函数定义时需要指定其返回类型和参数。num result;子程序类似于函数,但不返回值。

zhubeibei168的博客 1378

开关电源-LLC基本原理

本文详细介绍了LLC谐振变换器的兴起原因、基本工作原理、变换器特点及拓扑结构。重点讨论了半桥、全桥LLC及其软开关技术,包括零电压开关(ZVS)和零电流开关(ZCS)。通过理解简单的谐振电路(RL、RC、LC)来阐述LLC如何改变电压增益,以及如何通过调节频率实现输出电压的稳定性。

让你爱上电路设计 2万+

CString

WTL :: CString 包含在 WTL 头文件 atlmisc.h 中,并且在未定义宏 _WTL_NO_CSTRING 时可用。WTL :: CString 是一个非常独立的类,内存结构与 BSTR 类似,即有一个额外的字符串信息头标识字符串相关信息,信息头后紧跟有效字符串数据。此外它还借鉴 COM ,使用引用计数管理字符串对象指针的复制和对象的析构,使得对字符串对象的复制只是复制指

Wendysuly的专栏 1551

搞定ESD(五):静电放电问题分析与调试

前面深入分析了静电放电的干扰机理、耦合路径,从现在开始将进入下一个大家非常关注的环节:静电放电问题分析与调试,掌握静电放电问题的分析方法,快速锁定敏感设备或者耦合路径,可以达到事半功倍的效果。

记得诚 2793

CString 的成员函数详解

CString 的成员函数详解 CSTRING的成员函数详解 typedef ATL::CStringT< TCHAR, StrTraitMFC_DLL< TCHAR > > CString; CString的构造函数: 1 CString( ); 2 CString( const CString& stringSrc ); 3 CString( TCHAR ch, int nRepeat = 1 ); 4 CString( LPCTSTR lpch, int nLength

abc 4038

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

WTL::CString

 WTL :: CString 包含在 WTL 头文件atlmisc.h 中,并且在未定义宏 _WTL_NO_CSTRING 时可用。WTL :: CString 是一个非常独立的类,内存结构与 BSTR 类似,即有一个额外的字符串信息头标识字符串相关信息,信息头后紧跟有效字符串数据。此外它还借鉴 COM ,使用引用计数管

xbwee 的专栏 3636

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

ATL CString

将网络上关于ATL的CString用法整理了一下ATL中使用CString时,会提示说使用WTL::CString,(由于WTL也有CString,但却不受官方支持,最好使用ATL的实现)而我们只需要使用ATL::CString就可以了,这时只需要在stdafx.h头文件中加如下面2句即可: //注明使用ATL::CString而不是WTL::CString #define _WTL_NO_CSTRING #include 如果还有有问题,放到#include 前试试。来源 http://blog.sina

lily_86的专栏 3727

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

WTL中CString CPoint等出现冲突的问题

在做wtl工程的时候 我进行编译 出现了CString和CRect等模糊,冲突等的提示问题。我想可能是头文件的原因,挨个盘查,发现#include  和#include 有冲突,atlmisc.h头文件中包含了对cstring字符串的定义。但是我CString和atlimage.h都需要使用。后来从网上搜索资料,说是因为在编译CString时,分辨不清是wtl的cstring还是atl的c

amialy的专栏 2159

char装cstring_char*和CString转换

CString 是一种很特殊的 C++ 对象,它里面包含了三个值:一个指向某个数据缓冲区的指针、一个是该缓冲中有效的字符记数(它是不可存取的,是位于 CString 地址之下的一个隐藏区域)以及一个缓冲区长度。 有效字符数的大小可以是从0到该缓冲最大长度值减1之间的任何数(因为字符串结尾有一个NULL字符)。字符记数和缓冲区长度被巧妙隐藏。(1) char*转换成CString若将char*转换成...

weixin_39619174的博客 1448

关于CString

通过阅读本文你可以学习如何有效地使用 CString。  CString 是一种很有用的数据类型。它们很大程度上简化了MFC中的许多操作,使得MFC在做字符串操作的时候方便了很多。不管怎样,使用CString有很多特殊的技巧,特别是对于纯C背景下走出来的程序员来说有点难以学习。这篇文章就来讨论这些技巧。  使用CString可以让你对字符串的操作更加直截了当。这篇文章不是CString的完全手册,

VC++/MFC的专栏 1791

WTL中CString的使用问题

<br />atlmsic.h中定义的是WTL::CString,不过可以通过宏_WTL_USE_CSTRING和_WTL_NO_CSTRING来确定是否使用。<br />atlstr.h中定义的是ATL::CString。<br />如果按照说明,先定义_WTL_USE_CSTRING,然后包含atlmsic.h,就会出现CString定义不明的编译错误,其实就是编译器分不清你是用WTL::CString,还是ATL::CString。<br />避免这个问题的有两种方法:<br />1、只用atlstr

immortal_mcl的专栏 3694

BYTE CString之间的转化

在VC中,CSTRING类的用法形式多样,丰富多彩.但有时与传统数据类型之间的转换成为了很多人的难题. 下面我来简单介绍它们之间的关系. 1 如何实现cstring与char*之间的转换:   CString   m_cstr="abc";      char*   m_char="def";      char*   lp=m_cstr.GetBuffer(m_cstr.Get

kangyaping的专栏 1万+

CString类

·                 将 C 字符串的值分配到 CString对象: CString myString = "This is a test";·                 将一个 CString的值分配到另一个 CString对象: CString oldString = "This is a test";CString newString = oldSt

我的一些记录 2686

CString与const char*互转 深入详解

很多网上的文章只讲了用法,但是没有真正深入地去讲CString转换为啥可以这样做 CString其实是一个模板CStringT的别名 typedef ATL::CStringT< TCHAR, StrTraitMFC< TCHAR > > CString; 根据工程设置是Unicode还是多字节,存放的字符串TCHAR不同 这里假定大家都了解Unicode编程 而CStringT的基类是CSimpleStringT template< typen

tajon1226的专栏 6104

CString源码

CString使用的是引用技术,可以共享数据(这个大家都知道),另外空的CStirng是指向一个固定的地址的(_afxInitData).另外CStirng是有长度限制的2147483647(无符号int 的最大值).数据格式struct CStringData{ long nRefs; //引用记数 int nDataLength; //字符使用长度 int nAllocLength; //分配

Richard的专栏 2165
上一篇: CString 操作指南
下一篇: CString/string/char *比较详解
ShenRui
博客等级 码龄20年 63粉丝 36原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值