`
jgsj
  • 浏览: 951691 次
文章分类
社区版块
存档分类
最新评论

C++ 中数据类型互转

 
阅读更多

转自:http://hi.baidu.com/keenmeng_study/blog/item/427505245b40236c35a80f6f.html

传参数时不可以传CString ,CString 在ATL MFC中定义是不同的,而且在各个版本里也略有不同。注意。

有两方法LPCTSTR和GetBuffer()
看看这个

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当中,如果哪怕有一小块地方使用不当,其结果也会导致发生不可预知的错误

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

CString 转char *

CString cstr;

char *p = (LPSTR)(LPCTSTR)cstr;

string 转 CString
CString.format(”%s”, string.c_str());

char 转 CString
CString.format(”%s”, char*);

char 转 string
string s(char *);

string 转 char *
char *p = string.c_str();

CString 转 string
string s(CString.GetBuffer());

1,string -> CString
CString.format(”%s”, string.c_str());
用c_str()确实比data()要好.
2,char -> string
string s(char *);
只能初始化,在不是初始化的地方最好还是用assign().
3,CString -> string
string s(CString.GetBuffer());
GetBuffer()后一定要ReleaseBuffer(),否则就没有释放缓冲区所占的空间.

《C++标准函数库》中说的
有三个函数可以将字符串的内容转换为字符数组和C―string
1.data(),返回没有”/0“的字符串数组
2,c_str(),返回有”/0“的字符串数组
3,copy()

―――――――――――――――――――――

CString与int、char*、char[100]之间的转换- -

CString与int、char*、char[100]之间的转换- -

CString互转int

将字符转换为整数,可以使用atoi、_atoi64或atol。
而将数字转换为CString变量,可以使用CString的Format函数。如
CString s;
int i = 64;
s.Format(”%d”, i)
Format函数的功能很强,值得你研究一下。

void CStrDlg::OnButton1()
{
// TODO: Add your control notification handler code here
CString
ss=”1212.12″;
int temp=atoi(ss);
CString aa;
aa.Format(”%d”,temp);
AfxMessageBox(”var is ” + aa);
}

sart.Format(”%s”,buf);

CString互转char*

///char * TO cstring
CString strtest;
char * charpoint;
charpoint=”give string a value”;
strtest=charpoint;

///cstring TO char *

CString 转char *

CString cstr;

char *p = (LPSTR)(LPCTSTR)cstr;

string 转 CString
CString.format(”%s”, string.c_str());

char 转 CString
CString.format(”%s”, char*);

char 转 string
string s(char *);

string 转 char *
char *p = string.c_str();

CString 转 string
string s(CString.GetBuffer());

1,string -> CString
CString.format(”%s”, string.c_str());
用c_str()确实比data()要好.
2,char -> string
string s(char *);
只能初始化,在不是初始化的地方最好还是用assign().
3,CString -> string
string s(CString.GetBuffer());
GetBuffer()后一定要ReleaseBuffer(),否则就没有释放缓冲区所占的空间.

转的,请大家看时自己用心.

注意:CString --> string

CString na;
na=_T(m_name);//解决编码问题
string line(na.GetBuffer(na.GetLength()));
na.ReleaseBuffer(-1);
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
转自:http://blog.csdn.net/pizi0475/archive/2010/03/04/5346708.aspx
BSTR、LPSTR、LPWSTR、CString、VARIANT、COleVariant 、_variant_t、CComBSTR、_bstr_t
Visual C++.NET涉及到ATL/ATL Server、MFC和托管C++等多种编程方式,不仅功能强大而且应用广泛。在编程中,我们常常会遇到ANSI、Unicode以及BSTR不同编码类 型的字符串转换操作。本文先介绍基本字符串类型,然后说明相关的类,如CComBSTR、_bstr_t、CStringT等,最后讨论它们的转换方法, 其中还包括使用最新ATL7.0的转换类和宏,如CA2CT、CA2TEX等。
一、BSTR、LPSTR和LPWSTR
在Visual C++.NET的所有编程方式中,我们常常要用到这样的一些基本字符串类型,如BSTR、LPSTR和LPWSTR等。之所以出现类似上述的这些数据类 型,是因为不同编程语言之间的数据交换以及对ANSI、Unicode和多字节字符集(MBCS)的支持。
那么什么是BSTR、LPSTR以及LPWSTR呢?
BSTR(Basic STRing,Basic字符串)是一个OLECHAR*类型的Unicode字符串。它被描述成一个与自动化相兼容的类型。由于操作系统提供相应的 API函数(如SysAllocString)来管理它以及一些默认的调度代码,因此BSTR实际上就是一个COM字符串,但它却在自动化技术以外的多种 场合下得到广泛使用。图1描述了BSTR的结构,其中DWORD值是字符串中实际所占用的字节数,且它的值是字符串中Unicode字符的两倍。
LPSTR和LPWSTR是Win32和VC++所使用的一种字符串数据类型。LPSTR被定义成是一个指向以NULL(‘/0’)结尾的8位 ANSI 字符数组指针,而LPWSTR是一个指向以NULL结尾的16位双字节字符数组指针。在VC++中,还有类似的字符串类型,如LPTSTR、 LPCTSTR等,它们的含义如图2所示。
例如,LPCTSTR是指“long pointer to a constant generic string”,表示“一个指向一般字符串常量的长指针类型”,与C/C++的const char*相映射,而LPTSTR映射为 char*。
一般地,还有下列类型定义:
#ifdef UNICODE
typedef LPWSTR LPTSTR;
typedef LPCWSTR LPCTSTR;
#else
typedef LPSTR LPTSTR;
typedef LPCSTR LPCTSTR;
#endif
二、CString、CStringA 和 CStringW
Visual C++.NET中将CStringT作为ATL和MFC的共享的“一般”字符串类,它有CString、CStringA和CStringW三种形式,分 别操作不同字符类型的字符串。这些字符类型是TCHAR、char和wchar_t。TCHAR在Unicode平台中等同于WCHAR(16位 Unicode字符),在ANSI中等价于char。wchar_t通常定义为unsigned short。由于CString在MFC应用程序中经常用到,这里不再重复。
三、VARIANT、COleVariant 和_variant_t
在OLE、ActiveX和COM中,VARIANT数据类型提供了一种非常有效的机制,由于它既包含了数据本身,也包含了数据的类型,因而它可以实现各种不同的自动化数据的传输。下面让我们来看看OAIDL.H文件中VARIANT定义的一个简化版:
struct tagVARIANT {
VARTYPE vt;
union {
short iVal; // VT_I2.
long lVal; // VT_I4.
float fltVal; // VT_R4.
double dblVal; // VT_R8.
DATE date; // VT_DATE.
BSTR bstrVal; // VT_BSTR.
…
short * piVal; // VT_BYREF|VT_I2.
long * plVal; // VT_BYREF|VT_I4.
float * pfltVal; // VT_BYREF|VT_R4.
double * pdblVal; // VT_BYREF|VT_R8.
DATE * pdate; // VT_BYREF|VT_DATE.
BSTR * pbstrVal; // VT_BYREF|VT_BSTR.
};
};
显然,VARIANT类型是一个C结构,它包含了一个类型成员vt、一些保留字节以及一个大的union类型。例如,如果vt为VT_I2,那么我们可以从iVal中读出VARIANT的值。同样,当给一个VARIANT变量赋值时,也要先指明其类型。例如:
VARIANT va;
:: VariantInit(&va); // 初始化
int a = 2002;
va.vt = VT_I4; // 指明long数据类型
va.lVal = a; // 赋值
为了方便处理VARIANT类型的变量,Windows还提供了这样一些非常有用的函数:
VariantInit —— 将变量初始化为VT_EMPTY;
VariantClear —— 消除并初始化VARIANT;
VariantChangeType —— 改变VARIANT的类型;
VariantCopy —— 释放与目标VARIANT相连的内存并复制源VARIANT。
COleVariant类是对VARIANT结构的封装。它的构造函数具有极为强大大的功能,当对象构造时首先调用VariantInit进行初始 化, 然后根据参数中的标准类型调用相应的构造函数,并使用VariantCopy进行转换赋值操作,当VARIANT对象不在有效范围时,它的析构函数就会被 自动调用,由于析构函数调用了VariantClear,因而相应的内存就会被自动清除。除此之外,COleVariant的赋值操作符在与 VARIANT类型转换中为我们提供极大的方便。例如下面的代码:
COleVariant v1(”This is a test”); // 直接构造
COleVariant v2 = “This is a test”;
// 结果是VT_BSTR类型,值为”This is a test”
COleVariant v3((long)2002);
COleVariant v4 = (long)2002;
// 结果是VT_I4类型,值为2002
_variant_t是一个用于COM的VARIANT类,它的功能与COleVariant相似。不过在Visual C++.NET的MFC应用程序中使用时需要在代码文件前面添加下列两句:
#include “comutil.h”
#pragma comment( lib, “comsupp.lib” )
四、CComBSTR和_bstr_t
CComBSTR是对BSTR数据类型封装的一个ATL类,它的操作比较方便。例如:
CComBSTR bstr1;
bstr1 = “Bye”; // 直接赋值
OLECHAR* str = OLESTR(”ta ta”); // 长度为5的宽字符
CComBSTR bstr2(wcslen(str)); // 定义长度为5
wcscpy(bstr2.m_str, str); // 将宽字符串复制到BSTR中
CComBSTR bstr3(5, OLESTR(”Hello World”));
CComBSTR bstr4(5, “Hello World”);
CComBSTR bstr5(OLESTR(”Hey there”));
CComBSTR bstr6(”Hey there”);
CComBSTR bstr7(bstr6);
// 构造时复制,内容为”Hey there”
_bstr_t是是C++对BSTR的封装,它的构造和析构函数分别调用SysAllocString和SysFreeString函数,其他操作是借用BSTR API函数。与_variant_t相似,使用时也要添加comutil.h和comsupp.lib。
五、BSTR、char*和CString转换
(1) char*转换成CString
若将char*转换成CString,除了直接赋值外,还可使用CString::Format进行。例如:
char chArray[] = “This is a test”;
char * p = “This is a test”;
LPSTR p = “This is a test”;
或在已定义Unicode应的用程序中
TCHAR * p = _T(”This is a test”);
LPTSTR p = _T(”This is a test”);
CString theString = chArray;
theString.Format(_T(”%s”), chArray);
theString = p;
(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成员函数
(3) BSTR转换成char*
方法一,使用ConvertBSTRToString。例如:
#include
#pragma comment(lib, “comsupp.lib”)
int _tmain(int argc, _TCHAR* argv[]){
BSTR bstrText = ::SysAllocString(L”Test”);
char* lpszText2 = _com_util::ConvertBSTRToString(bstrText);
SysFreeString(bstrText); // 用完释放
delete[] lpszText2;
return 0;
}
方法二,使用_bstr_t的赋值运算符重载。例如:
_bstr_t b = bstrText;
char* lpszText2 = b;
(4) char*转换成BSTR
方法一,使用SysAllocString等API函数。例如:
BSTR bstrText = ::SysAllocString(L”Test”);
BSTR bstrText = ::SysAllocStringLen(L”Test”,4);
BSTR bstrText = ::SysAllocStringByteLen(”Test”,4);
方法二,使用COleVariant或_variant_t。例如:
//COleVariant strVar(”This is a test”);
_variant_t strVar(”This is a test”);
BSTR bstrText = strVar.bstrVal;
方法三,使用_bstr_t,这是一种最简单的方法。例如:
BSTR bstrText = _bstr_t(”This is a test”);
方法四,使用CComBSTR。例如:
BSTR bstrText = CComBSTR(”This is a test”);
CComBSTR bstr(”This is a test”);
BSTR bstrText = bstr.m_str;
方法五,使用ConvertStringToBSTR。例如:
char* lpszText = “Test”;
BSTR bstrText = _com_util::ConvertStringToBSTR(lpszText);
(5) CString转换成BSTR
通常是通过使用CStringT::AllocSysString来实现。例如:
CString str(”This is a test”);
BSTR bstrText = str.AllocSysString();
…
SysFreeString(bstrText); // 用完释放
(6) BSTR转换成CString
一般可按下列方法进行:
BSTR bstrText = ::SysAllocString(L”Test”);
CStringA str;
str.Empty();
str = bstrText;
CStringA str(bstrText);
(7) ANSI、Unicode和宽字符之间的转换
方法一,使用MultiByteToWideChar将ANSI字符转换成Unicode字符,使用WideCharToMultiByte将Unicode字符转换成ANSI字符。
方法二,使用“_T”将ANSI转换成“一般”类型字符串,使用“L”将ANSI转换成Unicode,而在托管C++环境中还可使用S将ANSI字符串转换成String*对象。例如:
TCHAR tstr[] = _T(”this is a test”);
wchar_t wszStr[] = L”This is a test”;
String* str = S”This is a test”;
方法三,使用ATL 7.0的转换宏和类。ATL7.0在原有3.0基础上完善和增加了许多字符串转换宏以及提供相应的类,它具有如图3所示的统一形式:
其中,第一个C表示“类”,以便于ATL 3.0宏相区别,第二个C表示常量,2表示“to”,EX表示要开辟一定大小的缓冲。SourceType和DestinationType可以是A、 T、W和OLE,其含义分别是ANSI、Unicode、“一般”类型和OLE字符串。例如,CA2CT就是将ANSI转换成一般类型的字符串常量。下面 是一些示例代码:
LPTSTR tstr= CA2TEX<16>(”this is a test”);
LPCTSTR tcstr= CA2CT(”this is a test”);
wchar_t wszStr[] = L”This is a test”;
char* chstr = CW2A(wszStr);
六、结语
几乎所有的程序都要用到字符串,而Visual C++.NET由于功能强大、应用广泛,因而字符串之间的转换更为频繁。本文几乎涉及到目前的所有转换方法。当然对于.NET框架来说,还可使用Convert和Text类进行不同数据类型以及字符编码之间的相互转换。
CString ,BSTR ,LPCTSTR之间关系和区别
CString是一个动态TCHAR数组,BSTR是一种专有格式的字符串(需要用系统提供的函数来操纵,LPCTSTR只是一个常量的TCHAR指针。
CString 是一个完全独立的类,动态的TCHAR数组,封装了 + 等操作符和字符串操作方法。
typedef OLECHAR FAR* BSTR;
typedef const char * LPCTSTR;
vc++中各种字符串的表示法
首先char* 是指向ANSI字符数组的指针,其中每个字符占据8位(有效数据是除掉最高位的其他7位),这里保持了与传统的C,C++的兼容。
LP的含义是长指针(long pointer)。LPSTR是一个指向以‘/0’结尾的ANSI字符数组的指针,与char*可以互换使用,在win32中较多地使用LPSTR。
而LPCSTR中增加的‘C’的含义是“CONSTANT”(常量),表明这种数据类型的实例不能被使用它的API函数改变,除此之外,它与LPSTR是等同的。
1.LP表示长指针,在win16下有长指针(LP)和短指针(P)的区别,而在win32下是没有区别的,都是32位.所以这里的LP和P是等价的.
2.C表示const
3.T是什么东西呢,我们知道TCHAR在采用Unicode方式编译时是wchar_t,在普通时编译成char.
为了满足程序代码国际化的需要,业界推出了Unicode标准,它提供了一种简单和一致的表达字符串的方法,所有字符中的字节都是16位的值,其数 量也可以满足差不多世界上所有书面语言字符的编码需求,开发程序时使用Unicode(类型为wchar_t)是一种被鼓励的做法。
LPWSTR与LPCWSTR由此产生,它们的含义类似于LPSTR与LPCSTR,只是字符数据是16位的wchar_t而不是char。
然后为了实现两种编码的通用,提出了TCHAR的定义:
如果定义_UNICODE,声明如下:
typedef wchar_t TCHAR;
如果没有定义_UNICODE,则声明如下:
typedef char TCHAR;
LPTSTR和LPCTSTR中的含义就是每个字符是这样的TCHAR。
CString类中的字符就是被声明为TCHAR类型的,它提供了一个封装好的类供用户方便地使用。
LPCTSTR:
#ifdef _UNICODE
typedef const wchar_t * LPCTSTR;
#else
typedef const char * LPCTSTR;
#endif
VC常用数据类型使用转换详解
先定义一些常见类型变量借以说明
int i = 100;
long l = 2001;
float f=300.2;
double d=12345.119;
char username[]=”女侠程佩君”;
char temp[200];
char *buf;
CString str;
_variant_t v1;
_bstr_t v2;
一、其它数据类型转换为字符串
短整型(int)
itoa(i,temp,10); //将i转换为字符串放入temp中,最后一个数字表示十进制
itoa(i,temp,2); //按二进制方式转换
长整型(long)
ltoa(l,temp,10);
二、从其它包含字符串的变量中获取指向该字符串的指针
CString变量
str = “2008北京奥运”;
buf = (LPSTR)(LPCTSTR)str;
BSTR类型的_variant_t变量
v1 = (_bstr_t)”程序员”;
buf = _com_util::ConvertBSTRToString((_bstr_t)v1);
三、字符串转换为其它数据类型
strcpy(temp,”123″);
短整型(int)
i = atoi(temp);
长整型(long)
l = atol(temp);
浮点(double)
d = atof(temp);
四、其它数据类型转换到CString
使用CString的成员函数Format来转换,例如:
整数(int)
str.Format(”%d”,i);
浮点数(float)
str.Format(”%f”,i);
字符串指针(char *)等已经被CString构造函数支持的数据类型可以直接赋值
str = username;
五、BSTR、_bstr_t与CComBSTR
CComBSTR、_bstr_t是对BSTR的封装,BSTR是指向字符串的32位指针。
char *转换到BSTR可以这样: BSTR b=_com_util::ConvertStringToBSTR(”数据”); //使用前需要加上头文件comutil.h
反之可以使用char *p=_com_util::ConvertBSTRToString(b);
六、VARIANT 、_variant_t 与 COleVariant
VARIANT的结构可以参考头文件VC98/Include/OAIDL.H中关于结构体tagVARIANT的定义。
对于VARIANT变量的赋值:首先给vt成员赋值,指明数据类型,再对联合结构中相同数据类型的变量赋值,举个例子:
VARIANT va;
int a=2001;
va.vt=VT_I4; //指明整型数据
va.lVal=a; //赋值
对于不马上赋值的VARIANT,最好先用Void VariantInit(VARIANTARG FAR* pvarg);进行初始化,其本质是将vt设置为VT_EMPTY,下表我们列举vt与常用数据的对应关系:
unsigned char bVal; VT_UI1
short iVal; VT_I2
long lVal; VT_I4
float fltVal; VT_R4
double dblVal; VT_R8
VARIANT_BOOL boolVal; VT_BOOL
SCODE scode; VT_ERROR
CY cyVal; VT_CY
DATE date; VT_DATE
BSTR bstrVal; VT_BSTR
IUnknown FAR* punkVal; VT_UNKNOWN
IDispatch FAR* pdispVal; VT_DISPATCH
SAFEARRAY FAR* parray; VT_ARRAY|*
unsigned char FAR* pbVal; VT_BYREF|VT_UI1
short FAR* piVal; VT_BYREF|VT_I2
long FAR* plVal; VT_BYREF|VT_I4
float FAR* pfltVal; VT_BYREF|VT_R4
double FAR* pdblVal; VT_BYREF|VT_R8
VARIANT_BOOL FAR* pboolVal; VT_BYREF|VT_BOOL
SCODE FAR* pscode; VT_BYREF|VT_ERROR
CY FAR* pcyVal; VT_BYREF|VT_CY
DATE FAR* pdate; VT_BYREF|VT_DATE
BSTR FAR* pbstrVal; VT_BYREF|VT_BSTR
IUnknown FAR* FAR* ppunkVal; VT_BYREF|VT_UNKNOWN
IDispatch FAR* FAR* ppdispVal; VT_BYREF|VT_DISPATCH
SAFEARRAY FAR* FAR* pparray; VT_ARRAY|*
VARIANT FAR* pvarVal; VT_BYREF|VT_VARIANT
void FAR* byref; VT_BYREF
_variant_t是VARIANT的封装类,其赋值可以使用强制类型转换,其构造函数会自动处理这些数据类型。
例如:
long l=222;
ing i=100;
_variant_t lVal(l);
lVal = (long)i;
COleVariant的使用与_variant_t的方法基本一样,请参考如下例子:
COleVariant v3 = “字符串”, v4 = (long)1999;
CString str =(BSTR)v3.pbstrVal;
long i = v4.lVal;
七、其它
对消息的处理中我们经常需要将WPARAM或LPARAM等32位数据(DWORD)分解成两个16位数据(WORD),例如:
LPARAM lParam;
WORD loValue = LOWORD(lParam); //取低16位
WORD hiValue = HIWORD(lParam); //取高16位
对于16位的数据(WORD)我们可以用同样的方法分解成高低两个8位数据(BYTE),例如:
WORD wValue;
BYTE loValue = LOBYTE(wValue); //取低8位
BYTE hiValue = HIBYTE(wValue); //取高8位
如何将CString类型的变量赋给char*类型的变量
1、GetBuffer函数:
使用CString::GetBuffer函数。
char *p;
CString str=”hello”;
p=str.GetBuffer(str.GetLength());
str.ReleaseBuffer();
将CString转换成char * 时
CString str(”aaaaaaa”);
strcpy(str.GetBuffer(10),”aa”);
str.ReleaseBuffer();
当我们需要字符数组时调用GetBuffer(int n),其中n为我们需要的字符数组的长度.使用完成后一定要马上调用ReleaseBuffer();
还有很重要的一点就是,在能使用const char *的地方,就不要使用char *
2、memcpy:
CString mCS=_T(”cxl”);
char mch[20];
memcpy(mch,mCS,20);
3、用LPCTSTR强制转换: 尽量不使用
char *ch;
CString str;
ch=(LPSTR)(LPCTSTR)str;
CString str = “good”;
char *tmp;
sprintf(tmp,”%s”,(LPTSTR)(LPCTSTR)str);
4、
CString Msg;
Msg=Msg+”abc”;
LPTSTR lpsz;
lpsz = new TCHAR[Msg.GetLength()+1];
_tcscpy(lpsz, Msg);
char * psz;
strcpy(psz,lpsz);
CString类向const char *转换
char a[100];
CString str(”aaaaaa”);
strncpy(a,(LPCTSTR)str,sizeof(a));
或者如下:
strncpy(a,str,sizeof(a));
以上两种用法都是正确地. 因为strncpy的第二个参数类型为const char *.所以编译器会自动将CString类转换成const char *.
CString转LPCTSTR (const char *)
CString cStr;
const char *lpctStr=(LPCTSTR)cStr;
LPCTSTR转CString
LPCTSTR lpctStr;
CString cStr=lpctStr;
将char*类型的变量赋给CString型的变量
可以直接赋值,如:
CString myString = “This is a test”;
也可以利用构造函数,如:
CString s1(”Tom”);
将CString类型的变量赋给char []类型(字符串)的变量
1、sprintf()函数
CString str = “good”;
char tmp[200] ;
sprintf(tmp, “%s”,(LPCSTR)str);
(LPCSTR)str这种强制转换相当于(LPTSTR)(LPCTSTR)str
CString类的变量需要转换为(char*)的时,使用(LPTSTR)(LPCTSTR)str
然而,LPCTSTR是const char *,也就是说,得到的字符串是不可写的!将其强制转换成LPTSTR去掉const,是极为危险的!
一不留神就会完蛋!要得到char *,应该用GetBuffer()或GetBufferSetLength(),用完后再调用ReleaseBuffer()。
2、strcpy()函数
CString str;
char c[256];
strcpy(c, str);
char mychar[1024];
CString source=”Hello”;
strcpy((char*)&mychar,(LPCTSTR)source);
关于CString的使用
1、指定 CString 形参
对于大多数需要字符串参数的函数,最好将函数原型中的形参指定为一个指向字符 (LPCTSTR) 而非 CString 的 const 指针。
当将形参指定为指向字符的 const 指针时,可将指针传递到 TCHAR 数组(如字符串 ["hi there"])或传递到 CString 对象。
CString 对象将自动转换成 LPCTSTR。任何能够使用 LPCTSTR 的地方也能够使用 CString 对象。
2、如果某个形参将不会被修改,则也将该参数指定为常数字符串引用(即 const CString&)。如果函数要修改该字符串,
则删除 const 修饰符。如果需要默认为空值,则将其初始化为空字符串 [""],如下所示:
void AddCustomer( const CString& name, const CString& address, const CString& comment = “” );
3、对于大多数函数结果,按值返回 CString 对象即可。
串的基本运算
对于串的基本运算,很多高级语言均提供了相应的运算符或标准的库函数来实现。
为叙述方便,先定义几个相关的变量:
char s1[20]=”dir/bin/appl”,s2[20]=”file.asm”,s3[30],*p;
int result;
下面以C语言中串运算介绍串的基本运算
1、求串长
int strlen(char *s); //求串s的长度
【例】printf(”%d”,strlen(s1)); //输出s1的串长12
2、串复制
char *strcpy(char *to,*from);//将from串复制到to串中,并返回to开始处指针
【例】strcpy(s3,s1); //s3=”dir/bin/appl”,s1串不变
3、联接
char *strcat(char *to,char *from);//将from串复制到to串的末尾,
//并返回to串开始处的指针
【例】strcat(s3,”/”); //s3=”dir/bin/appl/”
strcat(s3,s2); //s3=”dir/bin/appl/file.asm”
4、串比较
int strcmp(char *s1,char *s2);//比较s1和s2的大小,
//当s1<s2、s1>s2和s1=s2时,分别返回小于0、大于0和等于0的值
【例】result=strcmp(”baker”,”Baker”); //result>0
result=strcmp(”12″,”12″); //result=0
result=strcmp(”Joe”,”joseph”) //result<0
5、字符定位
char *strchr(char *s,char c);//找c在字符串s中第一次出现的位置,
//若找到,则返回该位置,否则返回NULL
【例】p=strchr(s2,’.'); //p指向”file”之后的位置
if(p) strcpy(p,”.cpp”); //s2=”file.cpp”
注意:
①上述操作是最基本的,其中后 4个操作还有变种形式:strncpy,strncath和strnchr。
②其它的串操作见C的<string.h>。在不同的高级语言中,对串运算的种类及符号都不尽相同
③其余的串操作一般可由这些基本操作组合而成
【例】求子串的操作可如下实现:
void substr(char *sub,char *s,int pos,int len){
//s和sub是字符数组,用sub返回串s的第pos个字符起长度为len的子串
//其中0<=pos<=strlen(s)-1,且数组sub至少可容纳len+1个字符。
if (pos<0||pos>strlen(s)-1||len<0)
Error(”parameter error!”);
strncpy(sub,&s[pos],len); //从s[pos]起复制至多len个字符到sub
////////////////////////////////////////////////////////////////////////

转自:http://blog.csdn.net/alien73/archive/2008/12/08/3477033.aspx

几种c/c++中字符串转整形的方法

1.自己写一个函数(c/c++)

#include <stdio.h>

#include <assert.h>

/* my string to integer function */

int myfun(char *str){

int i = 0,n = 0,flag = 1;

if(str[0] == '-')

i = 1;flag = -1;

for(; str[i] != '/0' ; i++){

assert(str[i] >= '0' && str[i] <= '9');

n = str[i] - '0' + n*10;

}

return n*flag;

}

int main(int argc, char *argv[])

{

int a;

char str[] = "1024";

a = myfun(str);

printf("%d/n",a);

return 0;

}

2.使用c标准库中的atoi函数(c/c++)

#include <stdio.h>

#include <stdlib.h>

int main(int argc, char *argv[])

{

int a;double d;

char str[] = "1024";

char strd[] = "3.1415";

a = atoi(str);d =atof(strd);

printf("%d/n",a);

printf("%g/n",d);

return 0;

}

#include <iostream>

#include <string>

using namespace std;

int main(int argc, char *argv[])

{

int a;

string str = "1024";

a = atoi(str.c_str());

cout << a <<endl;

return 0;

}

其他相关函数还有atof,atol等。

3.使用sscanf函数(c/c++)

#include <stdio.h>

int main(int argc, char *argv[])

{

int a;double d;

char str[] = "1024";

char strd[] = "3.1415";

sscanf(str,"%d",&a);

sscanf(strd,"%lf",&d);

printf("%d/n",a);

printf("%g/n",d);

return 0;

}

4.使用c标准库中的strtol函数(c/c++)

#include <stdio.h>

#include <stdlib.h>

int main(int argc, char *argv[])

{

int a,hex_a;double d;

char str[] = "1024";

char hex_str[] = "ff";

char strd[] = "3.1415";

a = strtol(str,NULL,10);hex_a = strtol(hex_str,NULL,16);

d =strtod(strd,NULL);

printf("%d/n",a);

printf("%d/n",hex_a);

printf("%g/n",d);

return 0;

}

其他相关函数还有strtoul,将字符串转换成无符号的长整型数。

5.使用c++中的字符串流istringstream(c++)

#include <iostream>

#include <string>

#include <sstream>

using namespace std;

int main(int argc, char *argv[])

{

int a;

string str = "-1024";

istringstream issInt(str);

issInt >> a;

cout << a <<endl;

return 0;

}

不过,GCC(2.95.2)及以前版本并不支持sstream。

6.使用boost库中的lexical_cast函数(c++)

可以到www.boost.org下载最新的boost库,设置IDE的include路径就可以使用大部分boost功能了,具体可以参考http://www.stlchina.org/twiki/bin/view.pl/Main/BoostChina。

#include <boost/lexical_cast.hpp>

#include <iostream>

int main()

{

using boost::lexical_cast;

try{

int a = lexical_cast<int>("1024");

//int a = lexical_cast<int>("xxx"); // exception

double d = lexical_cast<double>("3.14194");

std::cout<<a<<std::endl;

std::cout<<d<<std::endl;

}catch(boost::bad_lexical_cast& e){

std::cout<<e.what()<<std::endl;

}

return 0;

}

//////////////////////////////////////////////////

转自:http://blog.chinaunix.net/u/11234/showart_116532.html

c++字符数组和字符串间的相互转换

把一个char数组,转换成一个string。
char *tmp1; string tmp2; /* read data into tmp1 */ /* tmp1 now has 1-10 megs of data in it */ tmp2 = tmp2.insert(0, tmp1);
把一个string转换到一个char数组。
char tmp1[]; string tmp2;
strncpy(tmp1,tmp2.c_str(),temp2.length());

分享到:
评论

相关推荐

    C++实现的线性重采样,包括数据类型转换,IQ实数互转,上下变频等。使用Qt做了一个简单的见面,可调用。

    C++实现的线性重采样,包括数据类型转换,IQ实数互转,上下变频等。使用Qt做了一个简单的见面,可调用。

    netty 在java中的字节码转换

    netty通信时经常和底层数据交互,C语言和java的数据类型和范围不同,通信时需要转化或兼容,附件为字节码、进制常用的转换类。

    double或float 转 8位或4位十六进制

    double与8位16进制互转;float与4位16进制互转。处理发送的消息,或者收到的消息很方便。

    Visual C++2010开发权威指南(共三部分).part1.rar

    1.8.6 安全数据类型 22 1.8.7 移动构造 23 1.9 支持开发并行程序 26 1.9.1 运行库支持native代码 26 1.9.2 调试和分析工具 29 1.10 对MFC的增强 31 1.10.1 任务对话框CTaskDialog 31 1.10.2 重启管理器(Restart ...

    C++网络爬虫项目

    编写单位: 达内IT培训集团 C++教学研发部 编写人员: 闵卫 定稿日期: 2015年11月20日 星期五WEBCRAWLER 网络爬虫实训项目 2 1. 项目概述 互联网产品形形色色,有产品导向的,有营销导向的,也有技术导向的,但是 ...

    Visual C++2010开发权威指南.part07

    17.4 通用类型系统(CTS) 661 17.5 通用语言规范(CLS) 663 17.6 程序集 664 17.6.1 元数据 664 17.6.2 程序集版本管理 665 17.6.3 微软中间语言(MSIL) 665 17.6.4 资源 666 17.7 .NET开发应用程序的范畴 666 ...

    ros2 msg转protobuf 案例

    ros2使用自建类型编译,订阅以及发布的demo,并且包括和protobuf互转的使用方式. 自建类型为序列化数据{uint32 size, uint8 data[] }

    C++逆向解析

    对C++开发的程序进行逆向工程, 识别其中的C++类型. 值得参考.

    Visual C++ 2005系列教程(包括PDF文档和PPT文件)

    C++ 2005系列课程(6):元数据与动态编程 VC++ 2005(7):泛型编程 VC++ 2005系列课程(8):与ISO-C++的集成 VC++ 2005系列课程(9):非托管互操作 VC++ 2005 :基础概览-20050420 VC++ 2005系列讲座 (5)指针与对象模型-...

    sxtwl_cpp:寿星天文历的C++实现版本

    本项目 / 。 详细介绍 sxtwl_cpp是一个的C++实现日历库。因为其依据天文历法算法实现,故...由于js代码为弱语言类型,在翻译成C++过程中,为了考虑精度使用的是long double类型.有些地方可以考虑用int类型替代 部分语法

    JniSample.rar

    android硬件开发经常需要使用jni的方式和C,C++层进行数据交互,demo部分总结了常见的一些复杂数据交互例子,包括常见的基本数据类型的传递以及复杂的对象互传,List集合互传,C++端主动调用java方法等。欢迎使用参考

    C#微软培训资料

    18.2 在 C #代码中调用 C++和 VB 编写的组件 .240 18.3 版 本 控 制 .249 18.4 代 码 优 化 .252 18.5 小 结 .254 第五部分 附 录 .255 附录 A 关 键 字.255 附录 B 错 误 码.256 附录 C .Net 名字空间...

    机器学习互操作性的开放标准-C/C++开发

    开放式神经网络交换(ONNX)是一个...它定义了可扩展的计算图形模型,以及内置运算符和标准数据类型的定义。 当前,我们专注于推理(评分)所需的功能。 ONNX得到了广泛的支持,可以在许多框架,工具和艰苦的工作中找到

    Microsoft .NET Framework 4

    新的内存映射文件和数字类型。 更轻松的调试,包括转储调试、Watson 小型转储、64 位的混合模式调试和代码协定。 有关 CLR 和 BCL 的增强功能的完整列表,请转到此处。 Visual Basic 和 C# 语言中的创新,例如 ...

    微软讲师讲解VC++ 2005

    VC++ 2005(2)类型系统.ppt VC++ 2005(3)类型成员.doc VC++ 2005(3)类型成员.ppt VC++ 2005(5)指针与对象模型.pdf VC++ 2005(6)元数据与动态编程.doc VC++ 2005(6)元数据与动态编程.pdf VC++ 2005(7)泛型编程.doc ...

    电梯模拟系统

    实现电梯和乘客之间的互交功能。包括: InOut(Elevator &E,WQueue w[Maxfloor+1][2]) 操作结果:进行乘客的进出电梯活动。 NewClient(Elevator &E,WQueue w[5][2]) 操作结果:进入新乘客。 PrintStatus(Elevator &...

    C# 程序设计手册(WORD)

    数据型别 15 在变量宣告中指定型别 16 转型和型别转换 21 Boxing 和 Unboxing 24 使用 as 和 is 运算符进行安全转型 27 将字节数组转换为 int 29 将 string 转换为 int 30 在十六进制字符串和数字型别间转换 32 数组...

    java基础入门教程

    网 络为中 心 的 计 算 时 代 转 移 ,而 购 买 Java则 是 他 的 重 大 战 略 决 策的实施 部 署 。因 此 ,Java的 诞 生 必 将 对 整 个 计 算 机 产 业 发 生 深远的 影 响,对 传 统 的 计 算 模型 提 出 了 新 的 ...

Global site tag (gtag.js) - Google Analytics