10字符串

10字符串

1.字符串常量

一串以’\0’结尾的字符在C语言中被看作字符串

用双引号括起的一串字符是字符串常量,C语言自动为其添加’\0’结束符

2.字符数组和字符指针

  • 字符串的存储

    • C语言没有提供专门的字符串数据类型

    • 使用字符数组和字符指针来处理字符串

    • 字符数组:每个元素都是字符类型的数组

数组的最后一个元素必须是’\0’才表示字符串

  • 字符数组的初始化

    • 字符常量的初始化列表对数组初始化

      char str[6] = {'C','h','i','n','a','\0'};

    • 字符串常量直接对数组初始化

      char str[6] = {"China"};

      char str[6] = "China";

      char str[ ] = "China";

  • 字符指针

    还可以用字符指针来指向一个字符,如果让字符指针指向一个字符串常量

    char *pStr ="Hello China";

  • 字符是否可以修改问题:关键看字符指针指向的字符串被存储在哪个区域

    case 1:pStr是一个指向常量存储区中的字符串的指针变量

    char *pStr ="Hello China";

    char *pStr;

    pStr= "Hello China";

    • 字符串保存在只读的常量存储区

    • 可修改pStr的值(指向),但不可以对它所指向的存储单元进行写操作

    case 2:数组名str作为指针

    char str[]="Hello China";

    • 函数内定义,保存在动态存储区

    • 函数外定义,或定义为静态数组,字符串保存在静态存储区

    • 数组名str的值不可修改,是地址常量

    • 数组中存储的字符可以被修改

    case 3:pStr是一个指向不在常量存储区中的字符串的指针变量

    char str[]="Hello China";

    char *pStr;

    pStr = str;pStr = &str[0];

    • pStr的值(指向)可以被修改,它所指向的字符串也可以被修改

3.字符串处理函数

  • 按字符逐个访问or输入/输出

  • 按字符串整体输入/输出:

    • 不能输入带空格的字符串:

      1.用%d输入数字或%s输入字符串时,忽略空格、回车或制表符等空白字符,读到这些字符时,系统认为读入结束,因此不能输入带空格的字符串

      2.scanf()不读走回车,回车仍留在缓冲区中,回车需要加一个getchar(),被getchar()读走

      scanf("%s",str);

      printf("%s",str);

    • 可以输入带空格的字符串

      读入特性:

      1.可输入带空格的字符串,因为空格和制表符都是字符串的一部分

      2.空格和制表符都是字符串的一部分,以回车作为字符串的终止符,同时将回车从缓冲区读走,但不作为字符串的一部分

      gets(str);

      puts(str);

  • 对于缓冲区的解释:

    键盘输入都被保存在输入缓冲区中,直到用户输入回车,输入函数才去读缓冲区中的数据

  • 缓冲区溢出攻击

    世界上第一个缓冲区溢出攻击:Internet蠕虫,曾造成全球多台网络服务器瘫痪

    • 原因:gets()、scanf()、strcpy()等不限制字符串长度,不对数组越界进行检查和限制,导致有用的堆栈数据被覆盖,给黑客攻击以可乘之机

    • 防范方法:fgets(input, sizeof(input), stdin);限制输入字符串的长度,更灵活

    • n族字符串函数

  • scanf的优化:

    对于下面这段代码:假如格式不匹配,输入了非数字字符?

    1
    2
    3
    4
    do{
    printf("Input n:");
    ret = scanf("%d", &n);
    }while (ret != 1);

    scanf()按指定格式读取缓冲区中的数据,如果读取失败,则缓冲区中的非数字字符不会被读走,一直处于判断、读取、退出,判断、读取、退出,……(死机)

  • 判断scanf()返回成功读取的数据的个数,可以避免死机问题,但还需清空缓冲区

    1
    2
    3
    4
    5
    6
    7
    8
    do{
    printf("input n");
    ret=scanf("%d",&n);
    if(ret!=1)
    {
    while(getchar()!='\n');//清空缓冲区
    }
    }while(ret!=1);
  • 输出时的引号写法:\“

  • 字符串处理函数

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

    string length函数:strlen(字符串);

    • 计算方法:不包括\0的实际字符的个数

    • char str[10] = {"China"};
      printf("%d",strlen(str));
      <!--code2-->
      
      

    string copy函数:strcpy(目的字符串, 源字符串); (字符串不能用=整体复制)

    • 注意复制的方向,str2必须足够大

    string combination函数:strcat(目的字符串, 源字符串);

    • str2必须足够大!

    string comparison函数:strcmp(字符串1, 字符串2); (字符串不能用>,<,==比较大小)

    if (strcmp(str2, str1) == 0)

    • 计算方法

      当出现第一对不相等的字符时,就由这两个字符决定所在字符串的大小,返回其ASCII码比较的结果值

4.向函数传递字符串

向函数传递字符串时:既可用字符数组作函数参数,也可用字符指针作函数参数;传字符串的首地址,而非字符串中的全部字符

5.从函数返回字符串指针

返回字符串首地址