关闭

c++数据类型转换 sprintf、swprintf、wsprintf

12950人阅读 评论(0) 收藏 举报

sprintf、swprintf 
分别是对单字节/双字节字符格式化的,wsprintf根据预定义指示符的不同可以对单字节/双字节字符格式化。 wsprintf和swprintf比较,其实这两个函数对用用户来说是一样的,只不过前者是在 Winbase.h声明;后者是在stdio.h, stdlib.h文件中声明。 对于wsprintf, 在编译器编译过程中会检查你所定义的宏,然后将TCHAR.H文件中的以_tcs打头的函数转换成对应的str或wcs大头的函数。如果你要build一个使用UNICODE字符集的程序,则可以定义 _UNICODE宏。如果要build一个single-byte的程序则不需要定义任何宏,单字节字符程序时默认的(对于WIN32是这样,对于WINCE默认则是unicode字符程序)。  
//////////////////////////////////////////////// 和sprintf一样用, #include <stdio.h>  
int main() { 
 wchar_t a[123]; 
 swprintf(a, L"%f", 123.456);  wprintf(a); }  
注意第二个参数要加L,指定为宽字符字符串  
wsprintf是windows api,不支持浮点输出,swprintf是c库函数,用法和sprintf一样(格式都一样),只不过针对的是宽字符。

 

 

 

 

swprintf(FPSString, L"%f", FPS);   //正确

wsprintf(FPSString, L"%f", FPS);   //错误

 

wsprintf(wsprintfA)是API,sprintf是c函数,都是ansi,
对应的unicode分别是wsprintfW和swprintf

wsprintf 有1024字符限制,而且不支持浮点数。
所以结果不对。

 

wsprintf()包含在头文件windows.h
sprintf()包含在头文件stdio.h中。
wsprintf其实分为 wsprintfA 和 wsprintfW,前者对应 sprintf,后者对应 wsprintf。
wsprintf 有 1024 字符限制,而且不支持浮点数。
所以注意了,该函数不支持浮点数的输入输出

 

 

 

 

普通字符是用8位来表示的。如:
‘0' = 48 = \x30,在计算机内存中则表示为“30”
而同样的字符如果用TCHAR(在Windows操作系统上则为宽字符,也就是16位表示)表示,则为
‘0' = 48 = \x0030, 在计算机内存中表示为 “30” “00”。
所以这样的话,你用const char* 来强制转化的话会转化为8位来表示,所以16位中的“30”与“00”表示两个字符,因此当你输出第一个字符“1”时候,就会碰到“00”,而停止(C语言中字符串中遇到0字符表示字符串结束,所以输出就只有1了),这个出现的原因是由于内存中的存储顺序导致的。。

 

 

因为历史原因,使得 sprintf 和 swprintf 的参数格式不尽一致,所以,如果使用 _stprintf 时实现 ANSI 和 Unicode 双版本编程时,当指定使用 C99 以上标准编译 Unicode 版本时,通常会警告 swprintf 出错,此时可更换使用 snwprintf 代替(注意参数也要调整),即使用 _sntprintf 代替 _stprintf 实现功能。如果代码中已包含大量的 _stprintf 或 swprintf,就只能使用宏替换或自己实现。

 

 

 

格式化规定符:

  • %d 格式化为十进制有符号整数输出到缓冲区
  • %u 格式化为十进制无符号整数输出到缓冲区
  • %f 格式化为浮点数输出到缓冲区
  • %s 格式化为字符串输出到缓冲区
  • %c 格式化为单个字符输出到缓冲区
  • %e 格式化为指数形式的浮点数输出到缓冲区
  • %x 格式化为无符号以十六进制表示的整数(a-f小写输出)输出到缓冲区
  • %X 格式化为无符号以十六进制表示的整数(a-f大写输出)输出到缓冲区
  • %0 格式化为无符号以八进制表示的整数输出到缓冲区
  • %g 格式化为自动选择合适的表示法输出到缓冲区

说明:

  1. 可以在"%"和字母之间插进数字表示最大场宽。例如: %3d 表示输出3位整型数,不够3位右对齐。%9.2f 表示输出场宽为9的浮点数,其中小数位为2,整数位为6,小数点占一位,不够9位右对齐。%8s 表示输出8个字符的字符串,不够8个字符右对齐。如果字符串的长度、或整型数位数超过说明的场宽,将按其实际长度输出。但对浮点数,若整数部分位数超过了说明的整数位宽度,将按实际整数位输出;若小数部分位数超过了说明的小数位宽度,则按说明的宽度以四舍五入输出。另外,若想在输出值前加一些0,就应在场宽项前加个0。例如: %04d 表示在输出一个小于4位的数值时,将在前面补0使其总宽度为4位。如果用浮点数表示字符或整型量的输出格式,小数点后的数字代表最大宽度,小数点前的数字代表最小宽度。例如: %6.9s 表示显示一个长度不小于6且不大于9的字符串。若大于9,则第9个字符以后的内容将被删除。
  2. 可以在"%"和字母之间加小写字母l,表示输出的是长型数。例如: %ld 表示输出long整数,%lf 表示输出double浮点数。
  3. 可以控制输出左对齐或右对齐,即在"%"和字母之间加入一个"-" 号可说明输出为左对齐,否则为右对齐。例如: %-7d 表示输出7位整数左对齐。%-10s 表示输出10个字符左对齐。

 

 

转:c/c++数据类型转换1(float,char,string,CString) - [C/C++]

版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
http://www.blogbus.com/feles-logs/69452731.html

c/c++数据类型转换1(float,char,string,CString)

      Unicode(统一码、万国码、单一码)是一种在计算机上使用的字符编码。它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。1990年开始研发,1994年正式公布。随着计算机工作能力的增强,Unicode也在面世以来的十多年里得到普及。 在非 Unicode 环境下,由于不同国家和地区采用的字符集不一致,很可能出现无法正常显示所有字符的情况。微软公司使用了代码页(Codepage)转换表的技术来过渡性的部分解决这一问题,即通过指定的转换表将非 Unicode 的字符编码转换为同一字符对应的系统内部使用的 Unicode 编码。

     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;           wchar_t  
       wchar_t是C++的字符数据类型,char是8位字符类型,最多只能包含256种字符,许多外文字符集所含的字符数目超过256个,字符型无法表示。wchar_t数据类型为16位,所能表示的字符数远超char型。
  标准C++中的wprintf()函数以及iostream类库中的类和对象能提供wchar_t宽字符类型的相关操作。例如:
  #include <iostream>
  using namespace std;
  void main()
  {
  locale loc( "chs" );//定义“区域设置”为中文方式
  wcout.imbue( loc );//载入中文字符输入方式
  wchar_t str[]=L"中国";//定义宽字符数组,注意L是大写
  wcout<<str<<endl;//显示宽字符数组,下同
  wprintf(str);
  system("pause");
  }

一、其它数据类型转换为字符串string
1)短整型(int)
itoa(i,temp,10);///将i转换为字符串放入temp中,最后一个数字表示十进制
itoa(i,temp,2); ///按二进制方式转换 
2)长整型(long)
ltoa(l,temp,10); 
3)浮点数(float,double)
用fcvt可以完成转换,这是MSDN中的例子:
int decimal, sign; 
char *buffer; 
double source = 3.1415926535; 
buffer = _fcvt( source, 7, &decimal, &sign ); 
运行结果:source: 3.1415926535 buffer: '31415927' decimal: 1 sign: 0
decimal表示小数点的位置,sign表示符号:0为正数,1为负数 
4)CString变量
str = "2008北京奥运";
buf = (LPSTR)(LPCTSTR)str; 
5)BSTR变量
BSTR bstrValue = ::SysAllocString(L"程序员"); 
char * buf = _com_util::ConvertBSTRToString(bstrValue); 
SysFreeString(bstrValue); 
AfxMessageBox(buf); 
delete(buf); 
6)CComBSTR变量
CComBSTR bstrVar("test"); 
char *buf = _com_util::ConvertBSTRToString(bstrVar.m_str); 
AfxMessageBox(buf); 
delete(buf); 
7)_bstr_t变量
_bstr_t类型是对BSTR的封装,因为已经重载了=操作符,所以很容易使用
_bstr_t bstrVar("test"); 
const char *buf = bstrVar;///不要修改buf中的内容 
AfxMessageBox(buf);

通用方法(针对非COM数据类型)
sprintf完成转换
char buffer[200];
char c = '1';
int   i = 35;
long j = 1000;
float f = 1.7320534f;
sprintf( buffer, "%c",c);
sprintf( buffer, "%d",i);
sprintf( buffer, "%d",j);
sprintf( buffer, "%f",f);

二、字符串string转换为其它数据类型
temp="123456";
1)短整型(int)
i = atoi(temp); 
2)长整型(long)
l = atol(temp); 
3)浮点(double)
d = atof(temp); 
string s; d= atof(s.c_str()); 
4)BSTR变量 
BSTR bstrValue = ::SysAllocString(L"程序员"); 
...///完成对bstrValue的使用
SysFreeString(bstrValue); 
5)CComBSTR变量
CComBSTR类型变量可以直接赋值
CComBSTR bstrVar1("test");
CComBSTR bstrVar2(temp);
6)_bstr_t变量
_bstr_t类型的变量可以直接赋值
_bstr_t bstrVar1("test"); 
_bstr_t bstrVar2(temp);

7)string转char*

string 是c++标准库里面其中一个,封装了对字符串的操作 
把string转换为char* 有3中方法: 
1。data 
如: 
string str="abc"
char *p=str.data(); 
2.c_str 
如:string str="gdfd"
    char *p=str.c_str(); 
3 copy 
比如 
string str="hello"
char p[40]; 
str.copy(p,5,0); //这里5,代表复制几个字符,0代表复制的位置
*(p+5)='\0'//要手动加上结束符
cout < <p;

三、1. 其它数据类型转换到CString
使用CString的成员函数Format来转换,例如:
整数(int)           str.Format("%d",i); 
浮点数(float)    str.Format("%f",i); doubledb = 777.999; str.Format("%.8f",db); 保留8位小数
字符串指针(char *)可以直接赋值str = username; 
对于Format所不支持的数据类型,可以通过上面所说的关于其它数据类型转化到char *的方法先转到char *,然后赋值给CString变量。
注意:MFC智能设备string转Cstring
   string s=”123456”;   CString cstr;   cstr=s.c_str();

   2.CString 转double或float

(1)db = atof((LPCTSTR)str);

(2)通过自定义函数实现

void CStringToFloat(CString cstr ,double &f )//void CStringToFloat(CString cstr ,float&f )
{
int nLength = cstr.GetLength();
int nBytes = WideCharToMultiByte(CP_ACP,0,cstr,nLength,NULL,0,NULL,NULL); 

char* pContentBuff = new char[ nBytes + 1];
memset(pContentBuff,0,nBytes+1);
WideCharToMultiByte(CP_OEMCP, 0, cstr, nLength, pContentBuff, nBytes, NULL, NULL);
pContentBuff[nBytes] = 0; 
f = atof(pContentBuff);
}

   3.CString转int

CString如何转成int网上的介绍都是用atoi函数,但是CString 内部存储的是wchar_t 类型的字符,每个字符占两个字节,atoi的参数是char*,每个字符占一个字节 ,如果强制转换成char*,由于高位字节是空,所以就转成了只有第一个字符的串,这样是不对的.应该用_wtoi函数,这个函数的参数是wchar_t*,示例如下:
CString str("123");
int num = _wtoi(str);
同样,也有_wtof(),_wtol()等函数可供将CString 转成不同的数值类型.

   4. 平台VC2005,使用Unicode字符集。CString类型转换为char*或char[ ]
使用以前转换CString的方法或者网上别人的指导用法,都失效了
(1.strcpy_s( pchar, sizeof(pchar), mCString.GetBuffer(mCString.GetLength()) );不行,mCString.GetBuffer()返回的是wchar_t数组,使用Unicode字符集时,wchar_t无法自动转换为char*.
(2.strcpy_s(pchar, sizeof(pchar), (LPCSTR)_bstr_t(mCString));不行,"_bstr_t找不到识别符"
(3.char *pch = (T2A)(LPSTR)(LPCTSTR)mCString; 也不行,"T2A是没声明的标识符",我补加上相应头文件AtlConv.h
或AtlBase.h等的,也还是报错不改。
(4.char *pch = (LPSTR)(LPCTSTR)mCString; 这样没有报错,但pch只能获得CString的第一个字符而已,第一个换成
(char*),也只能获取第一个字符。
(5.CString.GetBuffer(CString.GetLength())不行。w_char*不能转为_char*。

用下面的函数
wstring MultCHarToWideChar(string str)
{
//获取缓冲区的大小,并申请空间,缓冲区大小是按字符计算的
int len=MultiByteToWideChar(CP_ACP,0,str.c_str(),str.size(),NULL,0);
TCHAR *buffer=new TCHAR[len+1];
//多字节编码转换成宽字节编码
MultiByteToWideChar(CP_ACP,0,str.c_str(),str.size(),buffer,len);
buffer[len]='\0';//添加字符串结尾
//删除缓冲区并返回值
wstring return_value;
return_value.append(buffer);
delete []buffer;
return return_value;
}
string WideCharToMultiChar(wstring str)
{
string return_value;
//获取缓冲区的大小,并申请空间,缓冲区大小是按字节计算的
int len=WideCharToMultiByte(CP_ACP,0,str.c_str(),str.size(),NULL,0,NULL,NULL);
char *buffer=new char[len+1];
WideCharToMultiByte(CP_ACP,0,str.c_str(),str.size(),buffer,len,NULL,NULL);
buffer[len]='\0';
//删除缓冲区并返回值
return_value.append(buffer);
delete []buffer;
return return_value;
}
于是使用
string mstring = WideCharToMultiChar( (LPCTSTR)mCString );
strcpy_s( pach, sizeof(pach), mstring.c_str() );
转换成功!

 

四、BSTR、_bstr_t与CComBSTR
CComBSTR 是ATL对BSTR的封装,_bstr_t是C++对BSTR的封装,BSTR是32位指针,但并不直接指向字串的缓冲区。
char *转换到BSTR可以这样: 
BSTR b=_com_util::ConvertStringToBSTR("数据");///使用前需要加上comutil.h和comsupp.lib
SysFreeString(bstrValue); 
反之可以使用char *p=_com_util::ConvertBSTRToString(b);delete p;

CComBSTR与_bstr_t对大量的操作符进行了重载,可以直接进行=,!=,==等操作,所以使用非常方便。

五、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与常用数据的对应关系:
Byte 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. 
DECIMAL FAR* pdecVal // VT_BYREF|VT_DECIMAL. 
IUnknown FAR* punkVal; // VT_UNKNOWN. 
IDispatch FAR* pdispVal; // VT_DISPATCH. 
SAFEARRAY FAR* parray; // VT_ARRAY|*. 
Byte 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; // Generic ByRef. 
char cVal; // VT_I1. 
unsigned short uiVal; // VT_UI2. 
unsigned long ulVal; // VT_UI4. 
int intVal; // VT_INT. 
unsigned int uintVal; // VT_UINT. 
char FAR * pcVal; // VT_BYREF|VT_I1. 
unsigned short FAR * puiVal; // VT_BYREF|VT_UI2. 
unsigned long FAR * pulVal; // VT_BYREF|VT_UI4. 
nt FAR * pintVal; // VT_BYREF|VT_INT. 
unsigned int FAR * puintVal; //VT_BYREF|VT_UINT. 
_variant_t是VARIANT的封装类,其赋值可以使用强制类型转换,其构造函数会自动处理这些数据类型。
使用时需加上#include <comdef.h>
例如:
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;

 

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:171576次
    • 积分:1557
    • 等级:
    • 排名:千里之外
    • 原创:8篇
    • 转载:39篇
    • 译文:0篇
    • 评论:17条
    最新评论