?
? ? ? ? C语言提供了许多操作字符串的函数,这些函数都包含在<string.h>库中,今天我们就来详细讲讲这些函数。
? ? ? ? strlen()是库中一个计算字符串长度的函数,用来返回字符串 ' \0 '之前的字符个数,不包括 ' \0 ',注意strlen必须以' \0 '结束。
char str[10] = "abcde";
int len_str = strlen(str); // 5
? ? ? ? strcpy是库中一个拷贝字符串函数,将source字符串,拷贝到dest目标字符串中。拷贝规则是将' \0 '及之前的字符串拷贝过去。拷贝的时候,source字符串中一定要有' \0 '。
? ? ? ? strcpy是一个将source字符串全部拷贝到dest中,包含' \0 ',那么我们拷贝的时候就一定要顾及source字符串的大小和dest字符串的大小,否则会出现很糟糕的现象。
char str1[10] = "abcde";
char str2[10];
strcpy(str2, str1); //此时str2中就是abcde
char str1[10] = "abcde";
char str2[15] = "hello world";
strcpy(str2, str1);//此时str2中仍是abcde
? ? ? ? 由于strcpy拷贝的时候可能会出现dest数组不够大,或者并不是想将source中所有字符都拷贝过去,那么我们可以用strncpy拷贝,这个就会增加一个参数:代表拷贝过去的字符个数。
char str1[10] = "abcdefg";
char str2[20] = "hello world";
strncpy(str2, str1, 3);//此时str2为"abclo world"
? ? ? ? 由此说明,strncpy其实起到的是一个覆盖作用。?将拷贝过去的字符,覆盖原有字符串的所处位置,剩下的字符不变。
? ? ? ? 那么就有一个问题了。如果我们默认num为要拷贝过去的字符个数。如果str1的字符数没有num大呢?那会如何拷贝?答案是剩下的用' \0 '来填补。
char str1[8] = "abcde";
char str2[20] = "hello world";
strncpy(str2, str1, 10);//abcde
? ? ? ? 我们可以看到原来str2中的' d '其实还是存在的,只不过前面五个用' \0 '来填充了,打印输出以' \0 '截止,故str2中可以说只剩abcde了。
? ? ? ? strcat是一个追加字符串函数,即在dest字符串的后面,追加source字符串。
? ? ? ? 注意:1)source字符串必须以' \0 '结尾。? ? ? ? 2)dest字符串必须是可修改的,即不能为字符串常量。? ? ? ? 3)dest字符串必须足够大。? ? ? ? 4)strcat不能自己给自己追加,有其他函数来自己给自己追加。(因为自己给自己追加的话,追加上去之后,原字符串已经变了了,那么继续追加的话,就会一直往后寻找' \0',因为原字符串正在边追加边变长,永远找不到头,直到越界。)
char str1[8] = "abcde";
char str2[40] = "hello world";
strcat(str2, str1);//str2此时为:hello worldabcde
? ? ? ? 同理,追加函数也有自己的限定字符个数的追加,同样增加参数:代表追加的字符个数。
? ? ? ? 注意:1)追加完了,会自动在追加过去的字符末尾增加' \0 '。? ? ? ? 2)同样,如果追加的字符个数小于num,那么不足的也会以' \0 '补齐。
char str1[8] = "abcde";
char str2[40] = "hello world";
strncat(str2, str1, 3);//str2此时为:hello worldabc
? ? ? ? strcmp函数是用来比较两个字符串的 ”大小“,这里所谓的大小呢,指的是比较从左往右第一个不同的字符的ASCII码值。如果前者小于后者,就返回一个负值;二者相等,返回0;前者大于后者就返回一个正值。
? ? ? ? 从左一直比较到字符串结束,直到比较到不同的字符。
char str1[8] = "abcde";
char str2[8] = "abfgh";
int ret = strcmp(str1, str2);
if (ret < 0)
printf("小于\n");
else if (ret == 0)
printf("等于\n");
else
{
printf("大于\n");
}
//结果为:小于
? ? ? ? 增加一个参数num,表示从左往右一共比较多少个字符。(只比较这num个字符,后面的不予比较)
char str1[8] = "abcde";
char str2[8] = "abfgh";
int ret = strncmp(str1, str2,2);
if (ret < 0)
printf("小于\n");
else if (ret == 0)
printf("等于\n");
else
{
printf("大于\n");
}
//结果为:等于
? ? ? ? 用于查找一个字符串中是否含有子字符串。如果存在,就返回这个子串在字符串中该子串的起始地址(即如果输出的话,就是从这个子串开始一直输出到字符串结束)。如果没有,就返回空NULL。
char str[20] = "hello nice world";
char* p1 = strstr(str, "nice");
printf("%s\n", p1);//输出结果为:nice world
char* p2 = strstr(str, "linux");
printf("%s\n", p2);//输出为(NULL)
? ? ? ? memcpy是负责拷贝两个独立的板块。?
? ? ? ? memcpy是一个拷贝函数,和strcpy不同的是,memcpy只将特定位置覆盖,而其余位置不变(即不会将' \0 '也拷贝过去)?。
void* memcpy(void* destination, const void* source, size_t num);
? ? ? ? 由此可知,memcpy使用于所有的数组,不局限于字符串。?
? ? ? ? 第一个参数:代表需要拷贝进去的字符串;第二个参数:代表从这个字符串中选出进行拷贝;size_t num:代表需要拷贝进去的字符串大小,单位是字节。
? ? ? ? 拷贝规则:1)函数从source的位置开始向后复制num个字节的数据到destination的内存位置。? ? ? ? 2)这个函数在遇到' \0'不会停下,而是将num个字节数完。? ? ? ? 3)如果source和destination有任何的重叠,拷贝结果是未定义的。(即不能自己给自己拷贝,因为拷贝后,原字符串该位置处已经改变,继续拷贝的话已经不是原来的值了)
char str1[20] = "hello world";
char str2[10] = "ccccccc";
memcpy(str1, str2, 9);
printf("%s", str1);//此时str1为:"ccclo world"
char str1[20] = "hello world";
char str2[10] = "ccc\0ccc";
memcpy(str1, str2, 9);
printf("%s", str1);//此时str1为:"ccc"
? ? ? ? 第二个拷贝,虽然输出结果为ccc,但其实是将"ccc\0ccc"全都拷贝进去的。
? ? ? ? memmove负责拷贝自己的内容。自拷贝。
void* memmove(void* destination, const void* source, size_t num);
?????????由此可知,memcpy使用于所有的数组,不局限于字符串。
? ? ? ???第一个参数:代表需要拷贝进去的字符串;第二个参数:代表从这个字符串中选出进行拷贝;size_t num:代表需要拷贝进去的字符串大小,单位是字节。
char str1[20] = "hello,nice,world";
memcpy(str1, str1+3, 4);
printf("%s", str1);//此时str1为:"lo,no,nice,world"
? ? ? ? 即将从下标为3的字符开始的后面四个字符,拷贝到str1的起始四个字符处。
int arr[] = { 1,2,3,4,5,6,7,8 };
memmove(arr, arr + 2, sizeof(int) * 2);
for (int i = 0; i < 8; i++)
{
printf("%d ", arr[i]);//3 4 3 4 5 6 7 8
}
? ? ? ? memcmp是任意类型数组比较大小,与strcmp比较方法一样。?
int memcmp(const void* p1, const void* p2, size_t num);
? ? ? ? ?p1,p2表示要比较的两个数组,size_t num:表示想要比较的个数的字节大小。
int arr1[] = { 1,2,3,4,5,6,7,8 };
int arr2[] = { 1,2,3,5,6 };
int ret = memcmp(arr1, arr2, sizeof(int)*4);
printf("%d", ret);//ret小于0
? ? ? ? 表示一共比较4个数,4 < 5,所以ret为负值。?
void* memset(void* ptr, int value, size_t num);
char str[20] = "hello,nice,world";
memset(str, 'x', 5);
printf("%s", str);//结果为:"xxxxx,nice,world"
? ? ? ? ?由此可以看出,memset是将数组从ptr开始的num个元素,变为value。num为字节个数
? ? ? ? 注意:memset一般只能对字符串进行修改,整型数组修改的话会错误。
? ? ? ? 对于数组修改函数,其实还有很多,我这里列出的都是一些很常用的,掌握这些就足够了。