深入字符串

时间:2021-07-18 01:18:24

注意*

字符串在内存中是连续的

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)

返回宽字节字符串长度,可以计算中英文