十一.字符串函数与内存函数

目录

一.求字符串长度

二.长度不受限制的字符串函数

1.strcpy函数

2.strcat函数

3.strcmp函数

三.长度受限制的字符串函数

1.strncpy函数

2.strncat函数

3.strncmp函数

四.字符串查找

1.strstr函数

2.strtok函数

3.strerror函数和perror函数

五.字符操作

1.字符分类

2.字符转换

六.字符操作函数

1.memcpy函数

2.memmove函数

3.memcmp函数

4.memset函数


一.求字符串长度

strlen函数

头文件:string.h

size_t strlen(const char* str)   //求字符串长度

注:

  • 字符串以 ‘’ 作为结束标志,strlen 返回的是在字符串中 ‘’ 前面出现的字符个数
  • 参数指向的字符串必须以  ‘’  结束 
  • 函数的返回值为 size_t ,无符号(unsigned)

用法演示:

#include <stdio.h>
#include <string.h>
 
int main()
{
    int len = strlen("abcdef");
    printf("%dn", len);
 
    return 0;
}

 运行结果:6

二.长度不受限制的字符串函数

1.strcpy函数

头文件:string.h

char *strcpy(char *dest, const char *src);  //字符串拷贝
//dest为目标空间,src为要拷贝的源字符串 

 注:

  • 字符串拷贝,将含有 ‘’ 的字符串复制到另一个地址空间,返回值的类型为 char*
  • 源字符串 src 必须以 ‘’ 结束
  • 会将源字符串 src 中的 ‘’ 一同拷贝到目标空间 dest
  • 目标空间必须足够大,以确保能够存放源字符串 dest (下面讲 strncmp 的时候演示)
  • 目标空间必须可变,即目标空间 dest 不可以被 const 声明

用法演示:

#include <stdio.h>
#include <string.h>
 
int main()
{
    char arr1[] = "abcdefghi";
    char arr2[] = "123";
    printf("拷贝前:%sn", arr1);
 
    strcpy(arr1, arr2);  //字符串拷贝(目标空间,源字符串)
 
    printf("拷贝后:%sn", arr1);
 
    return 0;
}

 运行结果:abcdefghi      123

2.strcat函数

头文件:string.h

char *strcat(char *dest, const char *src)  //字符串拼接
//dest为目标字符串,src为要拼接的源字符串

注:

  • src 所指向的字符串复制到 dest 所指向的字符串后面(删除 *dest 原来末尾的 ‘’
  • 源字符串 src 必须以 ‘’ 结束
  • 会将源字符串 src 中的 ‘’ 一同拷贝到目标空间 dest ,并删除 *dest 原来末尾的 ‘’
  • 目标空间必须足够大,以确保能够存放源字符串 dest
  • 目标空间必须可变,即目标空间 dest 不可以被 const 声明

 用法演示:

#include <stdio.h>
#include <string.h>
 
int main()
{
    char arr1[30] = "hello";
    char arr2[] = "world";
    
    strcat(arr1, arr2);
    printf("%sn", arr1);
 
    return 0;
}

运行结果:helloworld 

3.strcmp函数

头文件:string.h

int strcmp(const char *str1, const char *str2) //比较字符串的大小

用于比较两个字符串并根据比较结果返回整数, 两个字符串自左向右逐个字符相比,按照 ASCII值 大小相比较,从第一对字符开始比,如果相等则比下一对,直到出现不同的字符或遇 ‘’ 才停止。对比规则如下: 

第一个字符串>第二个字符串  返回正数
第一个字符串=第二个字符串  返回0
第一个字符串<第二个字符串  返回负数

 用法演示:

#include <stdio.h>
#include <string.h>
 
int main()
{   
    char *p1 = "abcdef";
    char *p2 = "aqwer";
    int ret = strcmp(p1, p2); // p1和p2比

    printf("%dn", ret);
 
    return 0;
}

运行结果:-1(负数)

三.长度受限制的字符串函数

1.strncpy函数

头文件:string.h

char *strncpy(char *dest, const char *src, size_t count)  //指定长度的字符串拷贝

注:

  • 从源字符串中拷贝 n 个字符到目标空间
  • 如果源字符串的长度小于 n,则拷贝完源字符串之后,在目标的后面追加 '',填充至 n 个
  • destsrc 不应该重叠(重叠时可以用更安全的 memmove 替代)
  • 目标空间必须足够大,以确保能够存放源字符串 dest
  • 目标空间必须可变,即目标空间 dest 不可以被 const 声明

用法演示:

#include <stdio.h>
#include <string.h>
 
int main()
{
    char arr1[5] = "abc";
    char arr2[] = "hello world";
    strncpy(arr1, arr2, 4);  //从arr2中拷贝4个到arr1
    printf("%sn", arr1);
 
    return 0;
}

 运行结果:hell

2.strncat函数

头文件: string.h

char *strncat(char *dest, const char *src, size_t count) //指定长度的字符串追加

注:

  • 追加 n 个字符到目标空间
  • 如果源字符串的长度小于 n,则只复制 ‘’ 之前的内容。

用法演示:

#include <stdio.h>
#include <string.h>
 
int main()
{
    char arr1[30] = "hello";
    char arr2[] = "world";
    strncat(arr1, arr2, 3);  //从arr2中取3个追加到arr1中
    printf("%sn", arr1);
 
    return 0;
}

 运行结果:hellowor

3.strncmp函数

头文件: string.h

int strncpy(const char *str1, const char *str2, size_t count) //指定长度的字符串比较

比较到出现另个字符不一样或者一个字符串结束或者 n 个字符全部比较完。

( 除了指定长度n,比较方式和 strcmp 一样 )

 用法演示:

#include <stdio.h>
#include <string.h>
 
int main()
{
    const char* p1 = "abczdef";
    const char* p2 = "abcqwer";
   
    int ret = strncmp(p1, p2, 1);   //int ret = strcmp(p1, p2);
    int ret1 = strncmp(p1, p2, 4);
    printf("%d %dn", ret, ret1);
 
    return 0;
}

 运行结果:0 1

四.字符串查找

1.strstr函数

头文件: string.h

char *strstr(const char str2,const char *str1)  //查找子串

返回字符串中首次出现子串的地址。若 str2 str1 的子串,则返回 str2 str1 中首次出现的地址。如果 str2 不是 str1 的子串,则返回 NULL 。 

用法演示:

#include <stdio.h>
#include <string.h>
 
int main()
{
    char* p1 = "abcdef";
    char* p2 = "def";
    char* p3 = "deg";
    char* ret1 = strstr(p1, p2); // 判断p2是否是p1的子串
    char* res2 = strstr(p1, p3);
    printf("%sn", ret1);
    printf("%sn", ret2);
 
    return 0;
}

 运行结果:def  null

2.strtok函数

头文件: string.h

char *strtok(char *str, const char *sep)  //切分字符串
  • sep参数是个字符串,定义了用作分隔符的字符集合
  • 第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记
  • strtok函数找到str中的下一个标记,并将其用 ‘’ 结尾,返回一个指向这个标记的指针。(注:strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。)
  • strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。
  • strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记。
  • 如果字符串中不存在更多的标记,则返回 NULL 指针。

总结:第一次调用,要传入原始字符串,第二次,如果还要解析原始字符串,传入NULL。

用法演示:切分ip地址

//切分ip地址

#include <stdio.h>
#include <string.h>
 
int main()
{
    char ip[] = "192.168.0.1";
   
    char* ret = strtok(ip, ".");
    printf("%sn", ret);
 
    ret = strtok(NULL, ".");
    printf("%sn", ret);
 
    ret = strtok(NULL, ".");
    printf("%sn", ret);
 
    ret = strtok(NULL, ".");
    printf("%sn", ret);
 
    return 0;
}

 运行结果:

 用法演示:切分邮箱地址

//切分邮箱地址

#include <stdio.h>
#include <string.h>
 
int main()
{
    char arr[] = "[email protected]";
    printf("原字符串: %sn", arr);
    
    const char* sep = "@."; // 创建sep
    char arr1[30];
    char* ret = NULL;
    strcpy(arr1, arr); // 将数据拷贝一份,保留arr数组的内容
 
    // 分行打印切割内容
    for (ret = strtok(arr, sep); ret != NULL; ret = strtok(NULL, sep)) {
        printf("%sn", ret);
    }
 
    printf("保留的原内容:%sn", arr1); // 保存的arr数组的内容
    printf("分割后原字符串被破坏: %sn", arr); // 分割后原字符串保留第一个分割符前的字符
 
    return 0;
}

运行结果:

3.strerror函数和perror函数

(1)strerror函数

头文件: string.h

char * strerror ( int errnum )

 返回错误码,返回错误码所对应的错误信息

  • 错误码       错误信息
    0 -          No error
    1 -          Operation not permitted
    2 -          No such file or directory
    ...

用法演示:

#include <string.h>
#include <stdio.h>
#include <errno.h>
 
int main()
{
    //errno 是一个全局的错误码变量
    //当c语言的库函数在执行过程中,发生了错误,
    //就会把对应的错误码赋值到errno中
    char* str = strerror(errno);
    printf("%sn", str);
 
    return 0;
}

运行结果:No error

关于errno:头文件:errno.h 

  • errno 是记录系统的最后一次错误代码,返回一个int 型的值,对应strerror的错误码
  • C语言标准库中有一个全局整形变量errno,当用户调用库函数发生错误时,库函数会将错误码(一个整形数值)存在errno中,将errno作为实参传入strerror函数中就可以将错误码(一个整形数值)翻译为对应的错误信息,并以字符串首地址的形式返回给用户,用户可以将描述错误信息的字符串打印出来。

(2)perror函数

头文件: string.h

void perror( const char *string )

形参中的const char *string是用户传入的自定义信息,perror函数可以自动访问全局变量errno,并将错误信息和用户传入的自定义信息一起打印出来,使用起来更加方便。 

用法演示:

#include <stdio.h>
#include <string.h>
#include <errno.h>  //必须包含的头文件
int main ()
{
    FILE * pFile;
    pFile = fopen ("unexist.ent","r");
    if (pFile == NULL) 
    {
       perror("error message :");
    }
    return 0;
}

 运行结果:

五.字符操作

1.字符分类

头文件: ctype.h

函数 如果他的参数符合下列条件就返回真
iscntrl 任何控制字符
isspace 空白字符:空格‘ ’,换页‘f’,换行'n',回车‘r’,制表符't'或者垂直制表符'v'
isdigit 十进制数字 0~9
isxdigit 十六进制数字,包括所有十进制数字,小写字母a~f,大写字母A~F
islower 小写字母a~z
isupper 大写字母A~Z
isalpha 字母a~z或A~Z
isalnum 字母或者数字,a~z,A~Z,0~9
ispunct 标点符号,任何不属于数字或者字母的图形字符(可打印)
isgraph 任何图形字符
isprint 任何可打印字符,包括图形字符和空白字符

用法演示:islower

#include <stdio.h>
#include <ctype.h>
 
int main()
{
    char ch1 = 'a';
    int ret = islower(ch1); // 判断ch1是否为小写
    printf("%dn", ret);
 
    char ch2 = 'B';
    int res = islower(ch2); // 判断ch2是否为小写
    printf("%dn", res);
 
    return 0;
}

运行结果:2(非0为真,表示小写)  0(假,表示大写) 

2.字符转换

头文件:ctype.h

int tolower ( int c );
int toupper ( int c );

用法演示:tolower(大写转为小写)

int main()
{
    char ch = tolower('Q'); // 大写转小写
    putchar(ch);
 
    return 0;
}

运行结果:q

用法演示:toupper(小写转为大写)

int main()
{
    char ch = toupper('q'); // 小写转大写
    putchar(ch);
    
    return 0;
}

运行结果:Q

六.字符操作函数

1.memcpy函数

头文件: string.h

void *memcpy(void *dest, const void *src, size_t count)
//src源内存地址,dest目标内存地址,count字节数
  • 从源内存地址 src 的起始位置开始拷贝 n 个字节到目标内存地址 dest
  • memcpy 没有刹车,这个函数遇到 ‘’ 并不会停下来
  • 如果 srcdest 有任何的重叠,复制的结果都是未定义的

用法演示:

#include <stdio.h>
#include <string.h>
 
int main()
{
    int arr1[] = {1, 2, 3, 4, 5};
    int arr2[5] = {0};
    memcpy(arr2, arr1, sizeof(arr1));
 
    // 打印 arr2 的内容
    int i = 0;
    for(i=0; i<5; i++) {
        printf("%d ", arr2[i]);
    }
 
    return 0;
}

 运行结果:1 2 3 4 5

2.memmove函数

头文件: string.h

void *memmove(void *dest, const void *src, size_t count)
  • 用于拷贝字节,如果目标区域和源区域有重叠时,memmove 能够保证源串在被覆盖之前将重叠区域的字节拷贝到目标区域中,但复制后源内容会被更改。
  • memcpy 的差别就是 memmove 函数处理的源内存块和目标内存块时可以重叠的
  • 如果原空间和目标空间出现重叠,应使用 memmove 函数处理 

用法演示:

#include <stdio.h>
#include <string.h>
 
int main()
{
    int arr[] = {1,2,3,4,5,6,7,8,9,10};
    int i = 0;
 
    memmove(arr+2, arr, 20);
 
    for(i=0; i<10; i++) {
        printf("%d ", arr[i]);
    }
 
    return 0;
}

 运行结果:1 2 1 2 3 4 5 8 9 10

3.memcmp函数

头文件: string.h

int memcmp(const void *ptr1, const void *ptr2, size_t num)

比较 ptr1 ptr2 指针开始的 n 个字节,按字节比较 

  • ptr1>ptr2  返回正数
  • ptr1=ptr2  返回 0
  • ptr1<ptr2  返回负数

memcmp 不同于 strcmpmemcmp 遇到 ‘’ 不会停止比较

用法演示:

#include <stdio.h>
#include <string.h>
 
int main()
{
    float arr1[] = {1.0, 2.0, 3.0, 4.0};
    float arr2[] = {1.0, 3.0};
    int ret = memcmp(arr1, arr2, 8); // arr1是否比arr2大,比较8个字节
    printf("%dn", ret);
    
    return 0;
}

 运行结果:-1(说明arr1的前八字节小于arr2的前八字节)

4.memset函数

头文件: string.h

void *memset(void *ptr, int value, size_t num)
  • 将某一块内存中的内容全部设置为指定的值,通常为新申请内存做初始化工作。
  • memset 是以字节为单位设置内存的

用法演示:把整型数组前20个字节设置为1

#include <stdio.h>
#include <string.h>
 
int main()
{
    // 40
    int arr[10] = {0};
    memset(arr, 1, 20); // 将前20个字节全部设置为1
 
    return 0;
}

 运行结果:


本文到此结束,码文不易,还请多多支持哦! 

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
)">
下一篇>>