当前位置: 代码迷 >> 综合 >> C++强制类型转换与字符类型之间的转换
  详细解决方案

C++强制类型转换与字符类型之间的转换

热度:76   发布时间:2023-10-20 12:31:48.0

1、强制类型转换

在实际工程中几乎是不可避免的,为此C++将强制类型转换分为4种不同的类型,以提供更加安全可靠的转换。

强制类型转换 说 明
static_cast 用于基本类型之间、有继承关系的类对象之间、类指针之间的转换
不能用于基本类型指针之间的转换
const_cast 用于去除变量的只读属性
强制转换的目标类型必须是指针或引用
reinterpret_cast 用于指针类型之间、整数和指针类型之间的转换
dynamic_cast 用于有继承关系的类指针之间、有交叉关系的类指针之间的转换
具有类型检查的功能
需要虚函数的支持

C++提供的4种强制类型转换以关键字的方式出现,使用语法为:xxx_cast<Target Type>(Expression)

#include <stdio.h>void static_cast_demo()
{int i = 0x12345;char c = 'c';int *pi = &i;char *pc = &c;c = static_cast<char>(i);pc = static_cast<char *>(pi); // Error,static_cast不能用于基本类型指针间的转换
}void const_cast_demo()
{const int &j = 1;int &k = const_cast<int &>(j);const int x = 2;int &y = const_cast<int &>(x);int z = const_cast<int>(x);  // Error,const_cast的目标类型必须是指针或引用
}void reinterpret_cast_demo()
{int i = 0;char c = 'c';int *pi = &i;char *pc = &c;pc = reinterpret_cast<char *>(pi);pi = reinterpret_cast<int *>(pc);pi = reinterpret_cast<int *>(i);c = reinterpret_cast<char>(i); // Error,reinterpret_cast不能用于基本类型间的转换
}void dynamic_cast_demo()
{int i = 0;int *pi = &i;char *pc = dynamic_cast<char *>(pi); // Error,dynamic_cast只能用于有继承关系或交叉关系的类指针间的转换,且类中必须有虚函数
}int main()
{static_cast_demo();const_cast_demo();reinterpret_cast_demo();dynamic_cast_demo();return 0;
}

2、字符与数字之间相互转换 

atoi、atof、atol、atoll等c++11标准函数将字符串转换成int、double、long、long long等

strtol、strtod、strtof、strtoll、strtold 函数将字符串转换成int、double、float、long long、long double等

其中atof函数使用例程如下:

/* atof example: sine calculator */
#include <stdio.h>      /* printf, fgets */
#include <stdlib.h>     /* atof */
#include <math.h>       /* sin */int main ()
{double n,m;double pi=3.1415926535;char buffer[256];printf ("Enter degrees: ");fgets (buffer,256,stdin);n = atof (buffer);m = sin (n*pi/180);printf ("The sine of %f degrees is %f\n" , n, m);return 0;
}Enter degrees: 45
The sine of 45.000000 degrees is 0.707101

strtol、strtod、strtof、strtoll、strtold 函数使用例程:

long strtol(const char * str,char ** str_end,int base);

long strtol(const char * restrict str,char ** restrict str_end,int base);

long long strtoll(const char * restrict str,char ** restrict str_end,int base);

str指向要解释的以空字符结尾的字节字符串,str_end指向的指针设置为指向经过最后解释的字符的字符。

其中参数base的范围为2~36,和0,它决定了字符串以被转换为整数的权值,可以被转换的合法字符依据base而定。当base为2时合法字符为‘0’,‘1’;base为8时合法字符为‘0’,‘1’,……‘7’;base为10时合法字符为‘0’,‘1’,……‘9’;base 为16时合法字符为‘0’,‘1’,……‘9’,‘a’,……‘f’;base为24时合法字符为‘0’,……‘9’,‘a’,……‘n’,base为36时,合法字符为‘0’,……‘9’,‘a’,……‘z’。

#include <stdio.h>
#include <stdlib.h>int main()
{char str[30] = "2030300 This is test";char *ptr;long ret;ret = strtol(str, &ptr, 10);printf("数字(无符号长整数)是 %ld\n", ret);printf("字符串部分是 |%s|", ptr);return(0);
}输出:
数字(无符号长整数)是 2030300
字符串部分是 | This is test|

float strtof(const char * restrict str,char ** restrict str_end);

double strtod(const char * str,char ** str_end);

double strtod(const char * restrict str,char ** restrict str_end);

long double strtold(const char * restrict str,char ** restrict str_end);

#include <stdio.h>
#include <errno.h>
#include <stdlib.h>int main(void)
{const char *p = "111.11 -2.22 Nan nan(2) inF 0X1.BC70A3D70A3D7P+6  1.18973e+4932zzz";printf("Parsing '%s':\n", p);char *end;for (double f = strtod(p, &end); p != end; f = strtod(p, &end)){printf("'%.*s' -> ", (int)(end-p), p);p = end;if (errno == ERANGE){printf("range error, got ");errno = 0;}printf("%f\n", f);}
}Parsing '111.11 -2.22 Nan nan(2) inF 0X1.BC70A3D70A3D7P+6  1.18973e+4932zzz':
'111.11' -> 111.110000
' -2.22' -> -2.220000
' Nan' -> nan
' nan(2)' -> nan
' inF' -> inf
' 0X1.BC70A3D70A3D7P+6' -> 111.110000
'  1.18973e+4932' -> range error, got inf
/* strtof example */
#include <stdio.h>      /* printf, NULL */
#include <stdlib.h>     /* strtof */int main ()
{char szOrbits[] = "686.97 365.24";char* pEnd;float f1, f2;f1 = strtof (szOrbits, &pEnd);f2 = strtof (pEnd, NULL);printf ("f1 = %f\n", f1);printf ("f1 = %f\n", f2);printf ("One martian year takes %.2f Earth years.\n", f1/f2);return 0;
}输出:f1 = 686.969971
f1 = 365.239990
One martian year takes 1.88 Earth years.

printf("%.*s\n",int,str) 的含义

// %.*s 其中的.*表示显示的精度 对字符串输出(s)类型来说就是宽度
// 这个*代表的值由后面的参数列表中的整数型(int)值给出
// 例如:
printf("%.*s\n", 1, "abc");        // 输出a
printf("%.*s\n", 2, "abc");        // 输出ab
printf("%.*s\n", 3, "abc");        // 输出abc >3是一样的效果 因为输出类型type = s,遇到'\0'会结束

3、把数字转换成字符串string,to_string函数

string to_string (int val);
string to_string (long val);
string to_string (long long val);
string to_string (unsigned val);
string to_string (unsigned long val);
string to_string (unsigned long long val);
string to_string (float val);
string to_string (double val);
string to_string (long double val);

#include <iostream>   // std::cout
#include <string>     // std::string, std::to_stringint main ()
{std::string pi = "pi is " + std::to_string(3.1415926);std::string perfect = std::to_string(1+2+4+7+14) + " is a perfect number";std::cout << pi << '\n';std::cout << perfect << '\n';return 0;
}运行结果:pi is 3.141593 28 is a perfect number

除了to_string函数外sprintf 最常见的应用之一莫过于把整数打印到字符串中,所以spritnf 在大多数场合可以替代itoa例如
//把整数123 打印成一个字符串保存在s 中。
sprintf(s, "%d", 123); //产生"123"
可以指定宽度,不足的左边补空格:
sprintf(s, "%8d%8d", 123, 4567); //产生:" 123 4567"
当然也可以左对齐:
sprintf(s, "%-8d%8d", 123, 4567); //产生:"123 4567"
也可以按照16 进制打印:
sprintf(s, "%8x", 4567); //小写16 进制,宽度占8 个位置,右对齐
sprintf(s, "%-8X", 4568); //大写16 进制,宽度占8 个位置,左对齐

/* sprintf example */
#include <stdio.h>int main ()
{char buffer [50];int n, a=5, b=3;n=sprintf (buffer, "%d plus %d is %d", a, b, a+b);printf ("[%s] is a string %d chars long\n",buffer,n);return 0;
}[5 plus 3 is 8] is a string 13 chars long

 

  相关解决方案