注意*
字符串在内存中是连续的
H | E | L | L | O | \0 |
72 | 101 | 108 | 108 | 111 | 0 |
知识扩展*:C语言规定,字符串以0结尾
用数组和指针声明字符串
char str[0xFF] {"Hello"};
char* str1 {(char*) "Hello"];
字符串是一个常量类型,所以要用显示类型转换
如果当前计算机是中文编码GBK,则字符在内存中显示为
张 | 三 | \0 | ||
d5 | c5 | c8 | fd | 00 |
因为每个汉字是两个字节,而英文还是一个字节
如果用宽字节来声明字符串,则每个字符在内存中显示为两个字节,不论中英文
‘
H | e | 张 | 0 | ||||
48 | 00 | 65 | 00 | 20 | 5f | 00 | 00 |
假设编译器采用utf-16,则‘张’在内存中显示为0x5f20,此时输出张,控制台不一定能输出,因为编译器虽然认识张,但是控制台可能采用的ANSI编码,此时就要调用头文件locale,并且通过setlocale函数设置中文每个字符占用两字节
知识扩展*:以十六进制输出字符串每个字符
wchar_t wcharA[0xff] {"Hello"};
for(int x=0;x<10;x++)
{
std::cout<<std::hex<<wcharA[x]<<std::endl;
}
scanf输入字符串
这里假设输入的Name是tony,所以Name需要5个字节,四个字节是tony,最后一个字节放0,如果是’张三‘,则需要5个字节,因为中文占两个字节
char Name[0x5];
scanf("%s",Name);
printf("%s",Name);
wchar_t wcharA[0xFF];
wscanf ("%s", wcharA);
wprintf ("%s", wcharA);
wchar_t输入输出前要加w,如果要输出中文,还要设置对应的头文件
安全问题
因为字符串也是数组,如果输入的字符串长度超过了数组长度,可能就会造成数据越界访问攻击,输入的字符串多出的部分,可以达到修改数据 的目的。
scanf_s
scanf_s("%s",str,可接受的最大字符值)
特别注意*:std::cout会把char类型的指针当成字符串来处理,不显示地址,显示它的值
strlen
语法 strlen(str)
返回char类型的字符串长度,不能计算中文
wcslen
语法 wcslen(str)
返回宽字节字符串长度,可以计算中英文