字符串

一、字符串

字符串由字符组成并且以\0(null)字符结尾。字符根据不同的编码方式,会有不同的具体实现。ANSI编码单个由一个字节组成,Unicode编码单个字符有2个字节内码组成。

1.1、C字符串


Char类型与Byte类型

Char类型:

单个字节,sizeof(char)=1,取值范围为-128~127

Byte类型:

单个字节,unsign char 宏,取值范围为0~127


  • 指针方式定义

    char*buf="123456";//该字符串使用默认的ANSI编码,并且以占用1个字节空间的\0字符结尾

  • 数组方式定义

    char buf[]="123456";

  • 注意两种方式的区别,存放返回值

    • 指针方式定义的,到第一个\0字符结束
    • 数组方式定义的,中间可以包含\0字符

1.2、C++字符串


wchar_t 类型:

宽字符类型,Unicode编码字符,单个字符占用2个字节,\0字符同样占用2个字节


  • 标准库类string
    • "12345"默认的ANSI编码
    • L“12345”unicode编码
    • _T("12345")unicode编码
  • 指针方式定义
    • char*
    • wchar_t*
    • TCHAR*
  • 数组方式定义
    • char[]
    • wchar[]
    • TCHAR[]

1.3、C++/Cli字符串

  • 兼容C++字符串
  • String^ 引用,默认采用Unicode编码

1.4、C#字符串

​ String类,默认采用Unicode编码

1.5、Windows字符串

LPCTSTR:

L:表示long指针

P:表示指针

C:表示是一个常量,const

T:_T宏,Unicode与Ansi字符的表示

STR:表示是一个字符串

1.6、TCHAR.H

该头文件中有个TCHAR类型,根据程序定义的编码进行动态表示。如果定义了Unicode编码,则这个字符串表示unicode字符串,否则就是标准的ANSI字符

TCHAR wchar_t char
_tcscpy wcscpy strcpy
_tcslen wcslen strlen
_tcscmp wcscmp strcmp
_tcscat wcscat strcat
_stprintf_s swprintf_s sprintf_s
_tfopen_s _wfopen_s fopen_s

二、不同平台互操作

2.1、获取字符串的长度

  • sizeof

    获取字符串的字节长度,包含‘/0’

  • strlen

    获取多字节字符串中字符长度,不包含'/0'

  • wcslen

    获取宽字节字符串中字符长度,不包含'/0'

  • _tcslen

    获取宽字节/多字节字符串中字符长度,不包含‘/0’

[长度总结](https://blog.csdn.net/gongzhengyu/article/details/83176015)

2.2、char*与wchar_t*相互转换

2.3、char*,wchar_t*与string,wstring相互转换

  • 2.3.1 char*转换为string

    直接进行转换:

    const char* n;
    string temp(n);
    
  • 2.3.2 wchar_t*转换为wstring

    const wchar_t*n;
    wstring temp(n);
    
  • 2.3.3 string转换为char*

    string str="123456";
    int len =str.Length();
    char*cp = new char[len+1];
    strcopy(cp,str);
    
  • 2.3.4 wstring转换为wchar_t*

    wstring str=L"123456";
    int len = str.Length();
    wchar_t* cp = new wchar_t[len+1];
    wcscpy(cp,str);
    

2.4 String^与char*,wchar_t*转换

​ 需要包含头文件#include<marshal.h>

  • 2.4.1 char* 转换为String^

    char* buf = "这是什么类型的字符串";
    		String^ str = marshal_as<String^>(buf);
    
  • 2.4.2 wchar_t*转换为String^

    wchar_t* buf = "这是什么类型的字符串";
    		String^ str = marshal_as<String^>(buf);
    
  • 2.4.3 String^ 转换为const char*

    String^ str = gcnew String("中文字符类型");
    		marshal_context^ mc = gcnew marshal_context();
    		const  char* s = mc->marshal_as<const char*>(str);
    		 OutputDebugString(s);
    		 delete mc;
    
  • 2.4.4 String^转换为const wchar_t*

    String^ str = gcnew String("中文字符类型");
    		marshal_context^ mc = gcnew marshal_context();
    		const  wchar_t* s = mc->marshal_as<const wchar_t*>(str);
    		 OutputDebugString(s);
    		 delete mc;
    

2.5 arrary^ 与char*、wchar_t*的转换

  • 2.5.1、C++强制类型转换

    • 2.5.1.1 static_cast

      • 用法:

        整型和浮点型,字符型之间的相互转换。

      • 定义:

        • a.不能用于不同类型的指针之间的转换
        • b.不能用于整型与指针之间的互相转换
        • c.不能用于不同类型引用之间的转换
      • 示例:

        #include <iostream>
        using namespace std;
        class A
        {
        public:
            operator int() { return 1; }
            operator char*() { return NULL; }
        };
        int main()
        {
            A a;
            int n;
            char* p = "New Dragon Inn";
            n = static_cast <int> (3.14);  // n 的值变为 3
            n = static_cast <int> (a);  //调用 a.operator int,n 的值变为 1
            p = static_cast <char*> (a);  //调用 a.operator char*,p 的值变为 NULL
            n = static_cast <int> (p);  //编译错误,static_cast不能将指针转换成整型
            p = static_cast <char*> (n);  //编译错误,static_cast 不能将整型转换成指针
            return 0;
        }
        
    • 2.5.1.2 const_cast

      将const引用转换为同类型的非const引用

      const string s = "Inception";
      string& p = const_cast <string&> (s);
      string* ps = const_cast <string*> (&s);  // &s 的类型是 const string*
      
    • 2.5.1.3 reinterpret_cast

      • 用法:

        new_type a = reinterpret_cast <new_type> (value)

      • 定义:

        • a.用在任意指针(或引用)类型之间的引用
        • b.指针与足够大的整数类型之间的抓暖
        • c.不会进行安全检查,一定会执行转换
      • 示例:

        #include <iostream>
        using namespace std;
        class A
        {
        public:
            int i;
            int j;
            A(int n):i(n),j(n) { }
        };
        int main()
        {
            A a(100);
            int &r = reinterpret_cast<int&>(a); //强行让 r 引用 a
            r = 200;  //把 a.i 变成了 200
            cout << a.i << "," << a.j << endl;  // 输出 200,100
            int n = 300;
            A *pa = reinterpret_cast<A*> ( & n); //强行让 pa 指向 n
            pa->i = 400;  // n 变成 400
            pa->j = 500;  //此条语句不安全,很可能导致程序崩溃
            cout << n << endl;  // 输出 400
            long long la = 0x12345678abcdLL;
            pa = reinterpret_cast<A*>(la); //la太长,只取低32位0x5678abcd拷贝给pa
            unsigned int u = reinterpret_cast<unsigned int>(pa);//pa逐个比特拷贝到u
            cout << hex << u << endl;  //输出 5678abcd
            typedef void (* PF1) (int);
            typedef int (* PF2) (int,char *);
            PF1 pf1;  PF2 pf2;
            pf2 = reinterpret_cast<PF2>(pf1); //两个不同类型的函数指针之间可以互相转换
        }
        
    • 2.5.1.4 dynamic_cast

      用法同reinterpret_cast,不过执行的时候会先进行类型检查,类型不安全会返回NULL指针

      #include <iostream>
      #include <string>
      using namespace std;
      class Base
      {  //有虚函数,因此是多态基类
      public:
          virtual ~Base() {}
      };
      class Derived : public Base { };
      int main()
      {
          Base b;
          Derived d;
          Derived* pd;
          pd = reinterpret_cast <Derived*> (&b);
          if (pd == NULL)
              //此处pd不会为 NULL。reinterpret_cast不检查安全性,总是进行转换
              cout << "unsafe reinterpret_cast" << endl; //不会执行
          pd = dynamic_cast <Derived*> (&b);
          if (pd == NULL)  //结果会是NULL,因为 &b 不指向派生类对象,此转换不安全
              cout << "unsafe dynamic_cast1" << endl;  //会执行
          pd = dynamic_cast <Derived*> (&d);  //安全的转换
          if (pd == NULL)  //此处 pd 不会为 NULL
              cout << "unsafe dynamic_cast2" << endl;  //不会执行
          return 0;
      }
      
  • 2.5.2、arrary^转换为char*、wchar_t*

    pin_ptr<System::Byte> p = &byteArray[0];
        unsigned char* pby = p;
        char* pch = reinterpret_cast<char*>(pby);
    
posted @ 2020-06-17 12:18  ZOL  阅读(88)  评论(0)    收藏  举报
// 侧边栏目录