为文本编辑框IDC_edit定义了变量m_edit是CString的,我现在需要把这个变量转化为char的;请问
CString类型如何转化为char型

解决方案 »

  1.   

    CString转化成char*之一:强制类型转换为LPCTSTR;
      
      这是一种略微硬性的转换,有关“正确”的做法,人们在认识上
    还存在许多混乱,正确的使用方法有很多,但错误的使用方法可能与
    正确的使用方法一样多。
      我们首先要了解 CString是一种很特殊的 C++对象,它里面包含
    了三个值:一个指向某个数据缓冲区的指针、一个是该缓冲中有效的
    字符记数以及一个缓冲区长度。有效字符数的大小可以是从0 到该缓
    冲最大长度值减1 之间的任何数(因为字符串结尾有一个NULL字符)。
    字符记数和缓冲区长度被巧妙隐藏。
      除非你做一些特殊的操作,否则你不可能知道给CString 对象分
    配的缓冲区的长度。这样,即使你获得了该0 缓冲的地址,你也无法
    更改其中的内容,不能截短字符串,也绝对没有办法加长它的内容,
    否则第一时间就会看到溢出。
      LPCTSTR 操作符(或者更明确地说就是 TCHAR *操作符)在 CString
    类中被重载了,该操作符的定义是返回缓冲区的地址,因此,如果你
    需要一个指向 CString的字符串指针的话,可以这样做:
      
      CString s("GrayCat");
      LPCTSTR p = s;
      它可以正确地运行。这是由C 语言的强制类型转化规则实现的。
    当需要强制类型转化时,C++ 规测容许这种选择。比如,你可以将
    (浮点数)定义为将某个复数(有一对浮点数)进行强制类型转换后
    只返回该复数的第一个浮点数(也就是其实部)。可以象下面这样:
      Complex c(1.2f, 4.8f);
      float realpart = c;
      如果(float) 操作符定义正确的话,那么实部的的值应该是1.2 。
      这种强制转化适合所有这种情况,例如,任何带有 LPCTSTR类型
    参数的函数都会强制执行这种转换。于是,你可能有这样一个函数
    (也许在某个你买来的DLL 中):
      BOOL DoSomethingCool(LPCTSTR s);
      你象下面这样调用它:
      CString file("c:\\myfiles\\coolstuff")
      BOOL result = DoSomethingCool(file);
      它能正确运行。因为 DoSomethingCool函数已经说明了需要一个
    LPCTSTR 类型的参数,因此 LPCTSTR被应用于该参数,在 MFC中就是
    返回的串地址。
      
      如果你要格式化字符串怎么办呢?
      
      CString graycat("GrayCat");
      CString s;
      s.Format("Mew! I love %s", graycat);
      注意由于在可变参数列
      表中的值(在函数说明中是以“... ”表示的)并没有隐含一个
    强制类型转换操作符。你会得到什么结果呢?  一个令人惊讶的结果,我们得到的实际结果串是:
      "Mew! I love GrayCat" 。  因为 MFC的设计者们在设计 CString数据类型时非常小心, CString
    类型表达式求值后指向了字符串,所以这里看不到任何象 Format 或
    sprintf 中的强制类型转换,你仍然可以得到正确的行为。描述 CString
    的附加数据实际上在 CString名义地址之后。
      有一件事情你是不能做的,那就是修改字符串。比如,你可能会
    尝试用“, ”代替“. ”(不要做这样的,如果你在乎国际化问题,
    你应该使用十进制转换的 National Language Support特性,),下
    面是个简单的例子:  CString v("1.00"); // 货币金额,两位小数
      LPCTSTR p = v;
      p[lstrlen(p) - 3] = '','';
      这时编译器会报错,因为你赋值了一个常量串。如果你做如下尝
    试,编译器也会错:  strcat(p, "each");
      因为 strcat 的第一个参数应该是 LPTSTR 类型的数据,而你却
    给了一个 LPCTSTR。
      不要试图钻这个错误消息的牛角尖,这只会使你自己陷入麻烦!
      
      原因是缓冲有一个计数,它是不可存取的(它位于 CString地址
    之下的一个隐藏区域),如果你改变这个串,缓冲中的字符计数不会
    反映所做的修改。此外,如果字符串长度恰好是该字符串物理限制的
    长度(梢后还会讲到这个问题),那么扩展该字符串将改写缓冲以外
    的任何数据,那是你无权进行写操作的内存(不对吗?),你会毁换
    坏不属于你的内存。这是应用程序真正的死亡处方。
      

  2.   

    CString转化成char*之二:使用CString对象的GetBuffer方法;
      
      如果你需要修改 CString中的内容,它有一个特殊的方法可以使
    用,那就是 GetBuffer,它的作用是返回一个可写的缓冲指针。如果
    你只是打算修改字符或者截短字符串,你完全可以这样做:CString s(_T("File.ext"));
    LPTSTR p = s.GetBuffer();
    LPTSTR dot = strchr(p, ''.''); // OK, should have used s.Find...
    if(p != NULL)
    *p = _T(''\0'');
    s.ReleaseBuffer();
      这是 GetBuffer的第一种用法,也是最简单的一种,不用给它传
    递参数,它使用默认值 0,意思是:“给我这个字符串的指针,我保
    证不加长它”。当你调用 ReleaseBuffer时,字符串的实际长度会被
    重新计算,然后存入 CString对象中。
      必须强调一点,在 GetBuffer和 ReleaseBuffer之间这个范围,
    一定不能使用你要操作的这个缓冲的 CString对象的任何方法。因为
    ReleaseBuffer 被调用之前,该 CString对象的完整性得不到保障。
    研究以下代码:CString s(...);LPTSTR p = s.GetBuffer();//... 这个指针 p 发生了很多事情int n = s.GetLength(); // 很糟D!!!!! 有可能给出错误的答案!!!s.TrimRight(); // 很糟!!!!! 不能保证能正常工作!!!!s.ReleaseBuffer(); // 现在应该 OKint m = s.GetLength(); // 这个结果可以保证是正确的。s.TrimRight(); // 将正常工作。
      假设你想增加字符串的长度,你首先要知道这个字符串可能会有
    多长,好比是声明字符串数组的时候用:
      char buffer[1024];
      表示 1024 个字符空间足以让你做任何想做得事情。在 CString
    中与之意义相等的表示法:
      LPTSTR p = s.GetBuffer(1024);
      调用这个函数后,你不仅获得了字符串缓冲区的指针,而且同时
    还获得了长度至少为 1024 个字符的空间(注意,我说的是“字符”,
    而不是“字节”,因为 CString是以隐含方式感知 Unicode的)。
      同时,还应该注意的是,如果你有一个常量串指针,这个串本身
    的值被存储在只读内存中,如果试图存储它,即使你已经调用了 GetBuffer ,
    并获得一个只读内存的指针,存入操作会失败,并报告存取错误。我
    没有在 CString上证明这一点,但我看到过大把的 C程序员经常犯这
    个错误。
      C 程序员有一个通病是分配一个固定长度的缓冲,对它进行 sprintf
    操作,然后将它赋值给一个 CString:char buffer[256];
    sprintf(buffer, "%......", args, ...); // ... 部分省略许多细节
    CString s = buffer;
    虽然更好的形式可以这么做:CString s;
      s.Format(_T("%...."), args, ...);
      如果你的字符串长度万一
      超过 256个字符的时候,不会破坏堆栈。  
      另外一个常见的错误是:既然固定大小的内存不工作,那么就采
    用动态分配字节,这种做法弊端更大:int len = lstrlen(parm1) + 13  lstrlen(parm2) + 10 + 100;char * buffer = new char[len];sprintf(buffer, "%s is equal to %s, valid data", parm1, parm2);CString s = buffer;......delete [] buffer;
    它可以能被简单地写成:CString s;s.Format(_T("%s is equal to %s, valid data"), parm1, parm2);
      需要注意 sprintf例子都不是 Unicode就绪的,尽管你可以使用
    tsprintf以及用 _T() 来包围格式化字符串,但是基本思路仍然是在
    走弯路,这这样很容易出错。
      

  3.   

    (2) CString转换成char*   若将CString类转换成char*(LPSTR)类型,常常使用下列三种方法:   方法一,使用强制转换。例如: 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成员函数
      

  4.   

    char aa[10];
    CString ss;
    strcpy(aa,ss);
      

  5.   

    char hehe[CString.GetLenght()] = CString.GetBuffer(CString.GetLenght());
    CString.ReleaseBuffer
      

  6.   

    LPCSTR不是强制转换,这是CString的一个操作符。
    LPCSTR返回一个常量字符串的指针。
      

  7.   

    char aa[10];
    CString ss;
    strcpy(aa,ss);