C语言学习笔记--字符串操作

1、字符串基础
    字符串是一种重要的数据类型,但是C语言并没有显式的字符串数据类型,因为字符串以字符串常量的形式出现或者存储于字符数组中。
    字符串就是一串零个或多个字符,并且以一个位模式为全0的NUL字节结尾。因此,字符串所包含的字符内部不能出现NUL字节。NUL字节是字符串的终止符,但他本身并不是字符串的一部分,所以字符串的长度并不包括NUL字节。
2、字符串长度
    库函数strlen的原型如下:
    size_t strlen(char const *string)
    注意strlen返回值类型是一个size_t类型,这个类型是在头文件stddef.h中定义的,它是一个无符号整型类型。
    例如:
    if (strlen(x) >= strlen(y) ) ----
    if (strlen(x) - strlen(y) >= 0)---
    上面两条语句看上去是相等的,但实际上并不相等,第一条语句按照你预想的那样工作,但是第二条语句的结果将是永远是真。strlen的结果是一个无符号数,所以操作符>=左边的表达式也将是一个无符号数,而无符号数绝不可能是负的。
    如果把strlen的返回值强制转换为int,就可以消除这个问题
3、字符串复制
    库函数strcpy的原型如下:
    char *strcpy(char * dst, char const * src)
    这个函数把参数src字符串复制到dst参数。如果src和dst在内存中存在重叠,其结果是未定义的。
    由于dst参数将进行修改,所以它不能使用字符串常量。
    目标参数的以前内容将被覆盖并丢失。即使新的字符串比dst原先的内存更短,由于新字符串是以NUL字节结尾,所以老字符串最后剩余的几个字符也被有效地删除。
    程序猿必须保证目标字符数组的空间足以容纳需要复制的字符串。如果字符串比数组长,多余的字符仍被复制,它们将覆盖原先存储于数组后面的内存空间。strcpy无法结果这个问题,因为它无法判断目标字符数组的长度。
    返回值:指向目标字符数据的指针。
4、连接字符串
    库函数strcat的原型如下:
    char *strcat(char *dst, char const *src)
    函数功能是把一个字符串添加(连接)到另一个字符串的后面。
    函数要求dst参数原先已经包含了一个字符串(可以是空字符串)。它找到这个字符串的末尾,并把src字符串的一份拷贝添加到这个位置,如果dst和src的位置发生重叠,其结果是未定义的。
    和前面一样,程序猿必须保证目标字符数组剩余的空间足以保存整个源字符串。同时,你必须考虑原先存在的字符串
    返回值:指向目标字符数据的指针。
5、字符串比较
    库函数strcmp的原型如下:
    int strcmp(char const *s1, char const *s2)
    比较两个字符串涉及对两个字符串对应的字符逐个进行比较,直到发现不匹配为止。那个最先不匹配的字符中较“小”(也就是说,在字符集中的序数较小)的那个字符所在的字符串被认为“小于”另外一个字符串。如果其中一个字符串是另外一个字符串前面的一部分,那么它也被认为“小于”另外一个字符串,
    因为它的NUL结尾字节出现的更早。这种比较被称为“词典比较”
    返回值:如果s1小于s2,函数返回一个小于零(非零即为真)的值。如果s1大于s2,函数返回一个大于零(非零即为真)的值,如果两个字符串相等,函数就返回零(零就是假)
    例如函数:
    if (strcmp(a, b))
    这样比较是得不出真确结果的,更好的方法是把这个返回值与零进行比较。
6、长度受限的字符串函数
    char *strncpy(char *dst, char const *src, size_t len)
    char *strncat(char *dst, char const *src, size_t len)
    int strncmp(char const *s1; char const *s2; size_t len)
    strncpy()把源字符串的字符复制到目标数组。然而,它总是正好向dst写入len个字符,如果strlen(src)的值小于len,dst数组就用额外的NUL字节填充到len长度。如果strlen(src)的值大于或等于len,那么只有len个字符被复制到dst中。注意,它的结果将不会以NUL字节结尾。
    strncat(),他从src中最多复制len个字符到目标数组的后面。但是strncat总是在结果字符串后面添加一个NUL字节,
    strncmp(),比较两个字符串,但它最多比较len个字节
7、字符串查找基础
    a、查找一个字符串
    char *strchr(char const *str, int ch)
    char *strrchr(char const *str, int ch)
    注意它们的第2个参数是一个整型值。但是,它包含了一个字符值。strchr在字符串str中查找字符ch第一个出现的位置,找到后函数返回一个指向该位置的指针。如果该字符并不存在于字符串中函数就返回一个NULL指针。strrchr功能基本一致,只是它所返回的是一个指向字符串中该字符最后一次出现的位置(最右边那个),区分大小写
    b、查找任何几个字符
    char *strpbrk(char const *str, char const *group)
    查找任何一组字符第一次在字符串中出现的位置
    这个函数返回一个指向str中第一个匹配group中任何一个字符的字符位置。如果未找到匹配,函数返回一个NULL指针
    例如:
    char string[20] = "Hello there, honey.";
    char *ans;
    ans = strpbrk(string, "aeiou");
    ans所指向的位置时string+1,区分大小写
    3、查找一个子串
    char *strstr(char const *s1, char const *s2)
    这个函数在s1中查找整个s2第一次出现的位置,并返回一个执行该位置的指针。如果s2并没有完整的出现在s1的任何地方,函数返回一个NULL指针。如果第二个参数是一个空字符串,函数就返回s1.
    注意标准库中并没有strstr或strpbrk函数
8、警告的总结:
    1、应该使用有符号数的表达式中使用strlen函数
    2、在表达式中混用有符号数和无符号数
    3、使用strcpy函数把一个长字符串复制到一个较短的数组中,导致溢出
    4、使用strcat函数把一个字符串添加到一个数组中,导致数组溢出
    5、把strcmp函数的返回值当做bool值进行测试
    6、把strcmp函数的返回值与1和-1进行比较
    7、使用并非以NUL字节结尾的字符序列
    8、使用strncpy函数产生不以NUL字节结尾的字符串
    9、把strncpy函数和strxxx函数混用

9、sizeof和strlen的区别:

    strlen是C语言的库函数,如上所述,strlen 测量的是字符的实际长度,以'\0' 结束。

    sizeof是C语言的运算符,sizeof 测量的是字符的分配大小。其作用是返回一个对象或者类型在内存中所占用的字节数。

    注意:sizeof后面如果是类型则必须加括号,如 sizeof(char);而如果是变量名则可以不加括号,如 sizeof a; 但是建议使用时  均加上括号。sizeof不能返回动态地被分配的数组的大小。

     sizeof可以用类型做参数,strlen只能用char*做参数,且必须是以''\0''结尾的。

    .strlen的结果要在运行的时候才能计算出来,是用来计算字符串的长度,不是类型占内存的大小。而大部分编译程序在编译的时候就把sizeof计算过了是类型或是变量的长度。

    在子函数中,ziseof 会把从主函数中传进来的字符数组当作是指针来处理。指针的大小又是由机器来决定,而不是人为的来决定的。
    

猜你喜欢

转载自blog.csdn.net/tyustli/article/details/85331634