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

1、强制类型转换

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

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

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

#include 

void static_cast_demo()
{
    int i = 0x12345;
    char c = 'c';
    int *pi = &i;
    char *pc = &c;

    c = static_cast(i);
    pc = static_cast(pi); // Error,static_cast不能用于基本类型指针间的转换
}

void const_cast_demo()
{
    const int &j = 1;
    int &k = const_cast(j);

    const int x = 2;
    int &y = const_cast(x);

    int z = const_cast(x);  // Error,const_cast的目标类型必须是指针或引用
}

void reinterpret_cast_demo()
{
    int i = 0;
    char c = 'c';
    int *pi = &i;
    char *pc = &c;

    pc = reinterpret_cast(pi);
    pi = reinterpret_cast(pc);
    pi = reinterpret_cast(i);
    c = reinterpret_cast(i); // Error,reinterpret_cast不能用于基本类型间的转换
}

void dynamic_cast_demo()
{
    int i = 0;
    int *pi = &i;
    char *pc = dynamic_cast(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       /* printf, fgets */
#include      /* atof */
#include        /* 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 
#include 

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 
#include 
#include 

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       /* printf, NULL */
#include      /* 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    // std::cout
#include      // std::string, std::to_string

int 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 

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

 

你可能感兴趣的:(C++)