字符串
一、字符串
字符串由字符组成并且以\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.2.1 标准库函数转换
size_t mbstowcs(wchar_t *wcstr, const char *mbstr, size_t count)
size_t wcstombs(char *mbstr, const wchar_t *wcstr, size_t count)
char* setlocale (int category, const char* locale)
返回值:一旦转换失败,函数返回 static_caststd::size_t(-1)
参数:转换的目标参数为null的时候,返回不包含字符'/0'的需要的长度
-
2.2.1.1 setlocale函数
setlocale(A,B)函数位于头文件 #include<locale.h>,不但可以用来对当前程序进行地域设置(本地设置,区域设置)也可以用来获取当前程序的地域设置信息。
- A:用来设置地域设置的影响范围。
- B:设置的具体参数
- C:默认的地域设置
- “”:使用当前操作系统默认的地域设置
- NULL:返回当前地域设置的名称
- 返回值:
- 执行成功:返回一个只想字符串的指针,该字符串包含了当前地域设置的名称
- 执行失败:返回空指针NULL
- 如果程序中没有用setlocale函数设置地域等其他参数,那么程序运行时locale被初始化为默认的C locale,其采用的字符编码是所有本地ANSI字符集编码的公共部分,是用来书写C语言源程序的最小字符集。
-
2.2.1.2 mbstowcs函数
这里一般调用2次,确保字符串长度OK。
-
2.2.1.3 wcstombs函数
这里一般调用2次,确保字符串长度OK。
char*p = setlocale(LC_ALL, NULL);//C setlocale(LC_ALL, "chs");//Chinese (Simplified)_China.936 setlocale(LC_ALL, "C"); char* buf = "这是什么字符串";//多字节存储扩展ANSI 按照C语言,大小14 size_t len = strlen(buf);//14 size_t temp = mbstowcs(NULL, buf, 0);//7 wchar_t* b = new wchar_t[temp+1]; size_t t =mbstowcs(b, buf, wcslen(b) + 1); OutputDebugString(b); delete[] b;
-
-
2.2.2 参考
[setlocale函数1](https://blog.csdn.net/zhengudaoer/article/details/79794634?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.nonecase)
[C/C++中字符串转换](https://blog.csdn.net/aaron_lyn1985/article/details/80053910?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase)
[C/C++转换](https://www.cnblogs.com/buyishi/p/10460797.html)
[setlocale](https://www.cnblogs.com/lanhaicode/p/10659763.html)
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);

浙公网安备 33010602011771号