前言:
其实在c语言当中是没有字符串这一概念的,不像c++里面有string类型用来存放字符串。在c语言中我们只能把字符串放在字符串常量以及字符数组中。
1.常见字符串函数
1.1strlen
size_t strlen ( const char * str );
作用:用来求字符串中 '\0' 前面出现的字符个数(不包 含 '\0' )。
这里我们要注意的是,在定义字符数组的时候,我们需要给‘\0’留出空间,因为编译器会在字符串后面加一个‘\0’。
#include<stdio.h>
#include<string.h>
int main() {char arr[5] = "asdfg";printf("%zd\n", strlen(arr));return 0;
}
我们可以看到,如果我们没有手动在字符串后面加一个‘\0',并且还没有预留出一个位置用来编译器自动放‘\0'的时候,strlen在计算字符串大小的时候就会出错。
所以在使用strlen的时候,我们要注意字符串末尾是否有‘\0',要么是自己手动添加,要么是留出位置(空间)给编译器自动添加。
当然这种不初始化空间大小方式也可以:(编译器会自动给留出空间放’\0')
char arr[] = "asdfg";
printf("%zd\n", strlen(arr));
还需要注意的是strlen函数的返回值类型,是size_t而不是int.
size_t和int有什么区别呢?
size_t是无符号整数,也就意味着没有负数这一概念.
1.2.strcpy
char* strcpy(char * destination, const char * source );
这个是字符串复制函数,将source指向地址的字符覆盖destination指针指向的地址的元素,以source字符串的‘\0'结束。
要注意的是:
1.目标字符串的空间一定要足够。
2.源字符串一定以’\0'结尾。
3.会将源字符串中的 '\0' 拷贝到目标空间
1.3.strcat
char * strcat ( char * destination, const char * source );
字符串追加函数,用来在目标字符串后面接上源字符串
通俗的来说就是达到“abc"+"def"="abcdef"这一目的。
注意:
1.源字符串必须以 '\0' 结束。
2.目标空间必须有足够的大,能容纳下源字符串的内容。
3.目标空间必须可修改。
4.字符串不可以自己给自己追加。
为什么不可以自己给自己追加呢?
首先我们要知道,strcat函数追加的原理是在目标字符串的‘\0'处开始追加,直到源字符串的’\0'被追加过去后马上停止。也就意味着,如果是自己追加自己,在开始追加的时候就把目标字符串的‘\0’给覆盖了,由于目标字符串和源字符串是一个东西,所以发现源字符串的’\0‘找不到了。所以就会出错。
1.4.strcmp
int strcmp ( const char * str1, const char * str2 )
字符串比较函数:标准规定, 第一个字符串大于第二个字符串,则返回大于0的数字 第一个字符串等于第二个字符串,则返回0 第一个字符串小于第二个字符串,则返回小于0的数字。
那如何比较呢?
其实就是从第一个字符串开始,比较字典序大小,遇到不一样的就停止。
const char* str1 = "abcdef";
const char* str2 = "abc";const char* str3 = "abcdef";
const char* str4 = "abd";const char* str5 = "abc";
const char* str6 = "abc";
printf("%d\n", strcmp(str1, str2));
printf("%d\n", strcmp(str3, str4));
以上都是我们比较常用的一些字符串函数,下面来介绍一些升级版的字符串函数。
1.5.strncmp
char * strncpy ( char * destination, const char * source, size_t num );
我们发现它跟strcmp函数很像,而且同样也是实现字符串的比较功能,但是strncmp可以控制比较的长度,第三个参数表示只比较前num个字符的大小。
const char* str1 = "abcdef";
const char* str2 = "abc";
printf("%d\n", strncmp(str1, str2,3));
1.6.strncat
char * strncat ( char * destination, const char * source, size_t num );
跟strcat函数很像,而且同样也是实现字符串的追加功能,但是前者可以控制追加的长度,第三个参数表示只追加源字符串前num个字符。
char arr1[20] = "xxxxxxxxx";
char arr2[5] = "asdff";
printf("%s\n", strncat(arr1, arr2,2));
1.7.strncpy
拷贝num个字符从源字符串到目标空间。如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个。
1.8.strstr
char * strstr ( const char *str1, const char * str2);
查找字符串str1里面有没有出现str2所指字符串,如果有返回首次出现的位置。
#include <stdio.h>
#include <string.h>
int main ()
{char str[] ="This is a simple string";char * pch;pch = strstr (str,"simple");strncpy (pch,"sample",6);puts (str);return 0;
}
1.9.strtok
char * strtok ( char * str, const char * sep );
这个函数大家见的可能比较少,这是分割函数。
就是将一个字符串按照一个分割符集合去分割成各个部分。
1.sep参数是个字符串,定义了用作分隔符的字符集合 。
2.第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标 记。
3.strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。(注: strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容 并且可修改。)
4.strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串 中的位置。
5.strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标 记。
6.如果字符串中不存在更多的标记,则返回 NULL 指针。
使用strtok将字符串分割:
char str[] ="- This, a sample string.";char * pch;printf ("Splitting string \"%s\" into tokens:\n",str);pch = strtok (str," ,.-");while (pch != NULL){printf ("%s\n",pch);pch = strtok (NULL, " ,.-");}
char *p = "zhangpengwei@bitedu.tech";const char* sep = ".@";char arr[30];char *str = NULL;strcpy(arr, p);//将数据拷贝一份,处理arr数组的内容for(str=strtok(arr, sep); str != NULL; str=strtok(NULL, sep)){printf("%s\n", str);}
strtok
函数会返回分割后的子字符串的指针,如果没有可分割的字符串,返回 NULL
。请注意,在每次调用 strtok
函数时,第一个参数传入 NULL
,以便获取剩余的分割字符串。
2.常见内存函数
什么叫内存函数?
内存函数是指在 C 语言中用来操作内存的一组函数。这些函数允许开发者对内存进行分配、拷贝、比较和设置等操作,以满足程序的需求。
常见的内存函数包括:
malloc
:用于动态分配指定大小的内存空间。calloc
:用于动态分配指定数量和大小的内存空间,并将分配的内存初始化为零。realloc
:用于重新调整之前动态分配的内存空间的大小。free
:用于释放之前动态分配的内存空间。memcpy
:用于将源内存区域的内容复制到目标内存区域。memcmp
:用于比较两个内存区域的内容是否相同。memset
:用于将指定内存区域的内容设置为指定的值。- memmove:用于在内存中移动一块数据的内容。
这里我只讲后面几个。
2.1.memcpy
void * memcpy ( void * destination, const void * source, size_t num );
函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。 这个函数在遇到 '\0' 的时候并不会停下来。 如果source和destination有任何的重叠,复制的结果都是未定义的。
不同于strcpy,memcpy可以复制任何类型的数据。
#include <stdio.h>
#include <string.h>
struct {char name[40];int age;
} person, person_copy;
int main ()
{char myname[] = "Pierre de Fermat";/* using memcpy to copy string: */memcpy ( person.name, myname, strlen(myname)+1 );person.age = 46;/* using memcpy to copy structure: */memcpy ( &person_copy, &person, sizeof(person) );printf ("person_copy: %s, %d \n", person_copy.name, person_copy.age );return 0;
}
2.2.memmove
memmove
是一个 C 语言库函数,用于在内存中移动一块数据的内容。它的函数原型如下:
void *memmove(void *dest, const void *src, size_t n);
1.dest
是目标内存区域的指针,数据将被复制到此处。
2.src
是源内存区域的指针,要复制的数据来自此处。
3.n
是要复制的字节数。
memmove
函数将源内存区域中的数据复制到目标内存区域。与 memcpy
不同的是,memmove
函数可处理源和目标内存区域重叠的情况,确保数据被正确复制。
#include <stdio.h>
#include <string.h>int main() {char str[10] = "Hello";// 使用 memmove 将字符 'o' 移动到字符串开头memmove(str, str+4, 2);printf("%s\n", str); // 输出结果: "oHell"return 0;
}
2.3.memcmp
内存比较函数,比较从ptr1和ptr2指针开始的num个字节,在num个字节之前遇到不相等的就停下,返回值和strcmp一致。
int memcmp ( const void * ptr1,const void * ptr2,size_t num );
char buffer1[] = "DWgaOtP12df0";char buffer2[] = "DWGAOTP12DF0";int n;n=memcmp ( buffer1, buffer2, sizeof(buffer1) );if (n>0) printf ("'%s' is greater than '%s'.\n",buffer1,buffer2);else if (n<0) printf ("'%s' is less than '%s'.\n",buffer1,buffer2);else printf ("'%s' is the same as '%s'.\n",buffer1,buffer2);