1 数据类型转换
1.1 常用类型转换
从高到低的类型 : long double , double, float , unsigned long long,long long ,unsigned long , long, unsigned int, int。
排名的一个例外是当 int 和 long int 的大小相同时。在这种情况下,unsigned int 将超越 long int,因为它可以保存更高的值。
1.1.1 隐式转化
当 C++ 使用运算符时,它会努力将操作数转换为相同的类型。这种隐式或自动的转换称为类型强制。
规则 1:char、short 和 unsigned short 值自动升级为 int 值。这是因为无论何时在数学表达式中使用这些数据类型的值,它们都将自动升级为 int 类型。
规则 2:当运算符使用不同数据类型的两个值时,较低排名的值将被升级为较高排名值的类型。在下面的表达式中,假设 a 是一个 int 变量,而 b 是一个 double 变量,在运算发生前,a将升值成为double变量。
规则 3:当表达式的最终值分配给变量时,它将被转换为该变量的数据类型。如 c = a + b; 那么无论a,b的类型是什么,a+b都将会最终转为c 的类型。
1.1.2 强制转换
通过使用类型强制转换表达式来完成。类型强制转换表达式允许手动升级或降级值。它的一般格式如下:
static_cast<DataType>(Value)
其中 Value 是要转换的变量或文字值,DataType 是要转换的目标数据类型。以下是使用类型转换表达式的代码示例:
double number = 3.7;
int val;
val = static_cast<int>(number);
虽然 static_cast 是目前使用最多的类型强制转换表达式,但是 C++ 还支持两种较旧的形式,这也是程序员应该有所了解的,即 C 风格形式和预标准 C++ 形式。
C 风格的转换将要转换的数据类型放在括号中,位于值要转换的操作数的前面。因为类型转换运算符在操作数前面,所以这种类型转换表示法被称为前缀表示法,示例如下:
int b;
double a = (double)b ;
预标准 C++ 形式类型强制转换表达式也是将要转换的数据类型放在其值要转换的操作数之前,但它将括号放在操作数周围,而不是围绕数据类型。这种类型转换表示法被称为功能性表示法,示例如下:
int b=10 ;
int c = 4;
double a = b(double)/ c;
特别注意的是,在c++11中,增加了auto关键字,转换类型相对智能化
auto c=(int)(9.87) 结果c=9
(2)string与char * ,char arr[]
String----const char *
c_str()生成一个const char*指针,指向以空字符终止的数组。
例1:const char *c; string s=”1234”; c=s.c_str();cout<<c; 输出结果为1234
例2:string str=”lol”; char * ptr=new char[str.length()+1]; strcat(ptr,str)
String—char s[]
可以利用strcpy函数(需先转换成const char *)或者利用循环对字符数组逐一赋值
例:string s(‘test’);char str[10];
strcpy(str,s.c_str())
for(inti=0;i<s.length();i++) {str[i]=s[i]}
char s[]与char *------string
可以直接赋值 char *ptr; char arr[]; string s1=ptr; string s2=arr;
(3)char *与int
头文件:#include<stdlib.h>
atoi() 函数用来将字符串转换成整数(int),其原型为:intatoi (const char * str);
例:char *numchars=“1234”; int num=atoi(numchars); 结果为1234
itoa()函数用于整数到字符串的转换,其原型为:char*itoa(int value, char *string, int radix);
例:int num=1234; int radix=8; char res[20]; itoa(num,res,radix);
printf("%d(10)=%s(%d)\n",num,res,radix);//输出1234(10)=2322(8) 这里radix指的是进制
同时c++还提供标准库函数有:long int atol ( const char * str ); double atof (constchar* str);
stof()、strtod()、strtol()、strtoul()、atoll()、strtof()、strtold()、strtoll()、strtoull(),详情可在网上查阅。
(4)string与int
利用stoi()直接转换
例:string s=”1234”;int b=stoi(s) 结果为1234
利用atoi()间接转换
例:string s=”1234”;int b=atoi(s.c_str()) 结果为1234
(5)sprintf作用是将printf的输出结果保存在字符串数组中。
sprintf转换类型的功能比较强大
sprintf函数的格式:
int sprintf( char *string_buffer, const char *format_string[, args] );
除了前两个参数固定外,可选参数可以是任意个。buffer是字符数组名;format是格式化字符串(像:"%3d%6.2f%#x%o",%与#合用时,自动在十六进制数前面加上0x)。只要在printf中可以使用的格式化字符串,在sprintf都可以使用。其中的格式化字符串是此函数的精华。
(6)unsigned char[] 转 char[]
多个unsigned char 数组拼接以及数组间数据用"|“分隔,最后一个数组后不跟”|",以及数据中有 0x00,以下方法非常有用:
如果把unsigned char[]转为 char[] ,因为str判断以‘\0’结尾,这样会丢数据
同理:memcpy,strncpy 拷贝同样存在一些问题。
步骤: 1. 新建临时数组 char tmp_str[] ,初始char数组为0,最终结果字符串str_rfid
2. 循环要拼接的数组数量,新建函数pack_rfid_str(char* const str_out, u8* d_buf, int d_len);
3. 利用指针移动,将数组的数据拼接到临时数组中,并在每个数组后加字符 ‘|’
4.最终成型的结果不需要末尾跟 | ,那么就需要把临时char数组赋给str变量 str_rfid,然后memcpy拷贝,size_t n 最好用str_rfid.length() -1,减去的就是末尾 | ,而strlen()获取的则是包含’\0’的长度,-1报错。
char tmp_str[1024];
memset(tmp_str, 0, 1024);
std::string str_rfid;
for (i = 0; i < _process_data.rfid.label_cnts; i++)
{
pack_rfid_str(tmp_str + strlen(tmp_str),
_process_data.rfid.label[i].data,
_process_data.rfid.label[i].len);
sprintf(tmp_str + strlen(tmp_str), "|");
}
LOG_INFO("MASTER", "rfid info=%s", tmp_str);
str_rfid = tmp_str;
memcpy(_snd_msg.upload_data.car_ec_no, str_rfid.c_str(), str_rfid.length()-1);
int pack_rfid_str(char* const str_out, u8* d_buf, int d_len) {
int i = 0;
char *p_str;
str_out[0] = '\0';
for (i = 0; i < d_len; i++)
{
sprintf(str_out + strlen(str_out), "%02X", d_buf[i]);
}
return 0;
}
编码转换
1. UTF8转换为GB2312编码
std::string utf8_to_gb2312(char * in)
{
int nLen = MultiByteToWideChar(CP_UTF8, 0, in, -1, NULL, 0);
unsigned short * wszGBK = new unsigned short[nLen + 1];
memset(wszGBK, 0, nLen * 2 + 2);
MultiByteToWideChar(CP_UTF8, 0, in, -1, (LPWSTR) wszGBK, nLen);
nLen = WideCharToMultiByte(CP_ACP, 0, (LPWSTR) wszGBK, -1, NULL, 0, NULL,
NULL);
char *szGBK = new char[nLen + 1];
memset(szGBK, 0, nLen + 1);
WideCharToMultiByte(CP_ACP, 0, (LPWSTR) wszGBK, -1, szGBK, nLen, NULL,
NULL);
std::string strTemp(szGBK);
delete[] szGBK;
delete[] wszGBK;
return strTemp;
}
2. GB2312转换为UTF8编码
char* convertGB2312ToUTF8(const char* gb2312)
{
int len = MultiByteToWideChar(CP_ACP, 0, gb2312, -1, NULL, 0);
wchar_t* wstr = new wchar_t[len+1];
memset(wstr, 0, len+1);
MultiByteToWideChar(CP_ACP, 0, gb2312, -1, wstr, len);
len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL);
char* str = new char[len+1];
memset(str, 0, len+1);
WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, len, NULL, NULL);
if(wstr) delete[] wstr;
return str;
}