前段时间学习了字符函数和字符串函数,这里写篇文章总结一下~
——————————————————————
注意:每个函数都有相应的头文件,切记不可遗漏
strlen函数简单一句话就是求字符串长度的,注意是字符串,也可以是字符数组。
总结为以下几点:
1.字符串以 ‘\0’ 作为结束标志,strlen函数返回的是在字符串中 ‘\0’ 前面出现的字符个数(不包含 ‘\0’ )
2.参数指向的字符串必须要以 ‘\0’ 结束
3.注意函数的返回值为size_t,是无符号的
strlen函数的使用
#include
int main()
{
char arr[] = "abcd";
int len = strlen(arr);
printf("%d\n", len);
return 0;
}
有以下代码:
int main()
{
if (strlen("abc") - strlen("abcdef") > 0)
{
printf("大于\n");
}
else
{
printf("小于等于\n");
}
return 0;
}
strlen(“abc”)是3,strlen(“abcdef”)是6,3-6=-3,不满足条件,所以认为答案是小于等于,其实这是错误的。我们要注意:strlen函数的返回值是无符号的,3是无符号的数,6是无符号的数,两个数相减还是无符号的数,无符号的数没有负数只有整数,所以是大于。
如果要进行修改,把strlen强制转换成int 类型即可。
if ((int)strlen("abc") - (int)strlen("abcdef") > 0)
第一种方式:
计数器
#include
size_t my_strlen(char* str)
{
int count = 0;
while (*str != '\0')
{
count++;
str++;
}
return count;
}
int main()
{
char arr[] = "abcd";
size_t len = my_strlen(arr);
printf("%d\n", len);
return 0;
}
把字符数组传过去,str指向字符串的第一个元素,给个计数器,如果* str不为0,count加1,同时str地址加1,重复这样的过程,直到 * str等于0跳出循环,并且返回count 的值(count 的值就是字符串的长度)
第二种方式:
递归
int my_strlen(char* str)
{
if (*str == '\0')
{
return 0;
}
else
{
return 1 + my_strlen(str + 1);
}
}
int main()
{
char arr[] = "abcd";
int len = my_strlen(arr);
printf("%d\n", len);
return 0;
}
如果*str=0,就直接返回0;如果不是,返回1加再次调用这个函数,字符串的地址往后移动,进入这个函数再判断,循环这个过程,直到遇到\0。
第三种方式:
指针-指针
int my_strlen(char* str)
{
char* p = str;
while (*p != '\0')
{
p++;
}
return p - str;
}
int main()
{
char arr[] = "abcd";
int len = my_strlen(arr);
printf("%d\n", len);
return 0;
}
把str的地址赋给指针p,p指向的是字符串首元素的地址,解引用p如果不为斜杠0,地址+1,遇到斜杠0,返回此时p的地址减去字符串首元素的地址,就是字符串的长度。
strcpy的作用是拷贝字符串,把源头字符串拷贝到目标空间去
总结为以下几点:
源字符串必须以 ‘\0’ 结束。
会将源字符串中的 ‘\0’ 拷贝到目标空间。
目标空间必须足够大,以确保能存放源字符串。
目标空间必须可变。
strcpy函数的使用
#include
int main()
{
char arr1[20] = { 0 };
char arr2[] = "abcdef";
strcpy(arr1, arr2);
printf("%s\n", arr1);
return 0;
}
验证是否拷贝了斜杠0:
char arr1[20] = "ssssssssssss";
如果有斜杠0,则第7个” s “将被覆盖成斜杠0
还有一种情况,如果把字符串写成这样:
char arr2[7] = { 'a','b','c','d','e','f','\0' };
在这末尾记住要加上斜杠0,否则运行错误
目标空间必须可变:
char* arr1 = "xxxxxxxxxxx";
此时arr1是常量字符串,不可改,所以这样写也不行。
char* my_strcpy(char* dest, const char* str)
{
assert(dest != NULL);
assert(str != NULL);
char* a = dest;
while (*dest++ = *str++)
{
;
}
return a;
}
int main()
{
char arr1[20] = { 0 };
char arr2[] = "abcdef";
my_strcpy(arr1, arr2);
printf("%s\n", arr1);
return 0;
}
将str的字符串拷贝给dest,所以str用const修饰,防止改变;用assert保证两个指针的有效性,防止为空指针;当str的值不为斜杠0时,把值赋给dest,同时两边地址++,当str是斜杠0时,把斜杠0拷贝给dest,此时dest为斜杠0跳出循环;在此之前,用一个字符指针变量先把dest保存起来,最后返回这个指针变量。
总结一下:
源字符串必须以 ‘\0’ 结束。
目标空间必须有足够的大,能容纳下源字符串的内容。
目标空间必须可修改。
strcat函数的使用:
int main()
{
char arr1[20] = "hello";
char arr2[] = "world";
strcat(arr1, arr2);
printf("%s\n", arr1);
return 0;
}
目标空间必须有斜杠0,这样才能知道从哪开始接加字符串(覆盖了目标空间的斜杠0);源字符串也必须有斜杠0,这样才知道把多少字符串的内容接到目标空间后面(包括源字符串的斜杠0),并且目标空间必须足够大。
char* my_strcat(char* dest, char* str)
{
assert(dest);
assert(str);
char* a = dest;
while (*dest)
{
dest++;
}
while (*dest++ = *str++)
{
;
}
return a;
}
int main()
{
char arr1[20] = "hello";
char arr2[] = "world";
my_strcat(arr1, arr2);
printf("%s\n", arr1);
return 0;
}
将str的字符串拷贝给dest,所以str用const修饰,防止改变;用assert保证两个指针的有效性,防止为空指针;当解引用dest不为0,地址++,直到遇到斜杠0跳出循环;后面的跟strcpy函数的模拟实现相同。
字符串不可自己给自己加,否则会死循环。
规定:
第一个字符串大于第二个字符串,则返回大于0的数字
第一个字符串等于第二个字符串,则返回0
第一个字符串小于第二个字符串,则返回小于0的数字
int main()
{
int len = strcmp("abc", "abb");
printf("%d\n", len);//>0
int len1 = strcmp("abc", "abw");
printf("%d\n", len1);//<0
int len2 = strcmp("abc", "abc");
printf("%d\n", len2);//=0
return 0;
}
int my_strcmp(const char* str1, const char* str2)
{
assert(str1 && str2);
while (*str1 == *str2)
{
if (*str1 == '\0')
return 0;
str1++;
str2++;
}
return (*str1 - *str2);
}
int main()
{
int len = my_strcmp("abc", "abb");
printf("%d\n", len);
return 0;
}
返回的是整数,所以返回的类型是int 类型;两个字符串拿来作比较,所以用const防止被修改;用assert保证两个指针的有效性,防止为空指针;当两个字符串对应的字符相等时,两个地址同时++,只要有一个为斜杠0,两个字符串相等,返回0;如果不是,返回第一个字符串减去第二个字符串的数值。(返回3种情况:小于0,等于0,大于0,具体返回的值为多少不确定)
strncpy函数的作用与strcpy函数类似,只是长度受限制
总结:
拷贝num个字符从源字符串到目标空间。
如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个。
strncpy函数的使用:
int main()
{
char arr1[20] = "abcdef";
char arr2[] = "xxxxxxxxx";
strncpy(arr1, arr2, 5);
printf("%s\n", arr1);
return 0;
}
如果源字符串的个数小于要拷贝的个数,则补上\0。
strncat函数的作用与strcat函数类似,只是长度受限制
strncat函数的使用:
int main()
{
char arr1[20] = "abcdef";
char arr2[] = "xxxxxxxxx";
strncat(arr1, arr2, 5);
printf("%s\n", arr1);
return 0;
}
arr1后面加5个x,同时还有\0。
strncmp函数的作用与strcmp函数类似,只是长度受限制
strncmp函数的使用:
int main()
{
char arr1[] = "abcdef";
char arr2[] = "abcqty";
int len = strncmp(arr1, arr2, 3);
printf("%d\n", len);
return 0;
}
只比较两个字符串的前3个字符,则相等;如果限制的个数是4,则小于0。
strstr函数的作用:找str2字符串中与str1有共同的字符串,相当于str2是str1的子集,找到了则在str1与str2相同的位置开始打印str1,没找到则返回空(null)
int main()
{
char arr1[] = "abcdefghi";
char arr2[] = "cde";
char* len = strstr(arr1, arr2);
printf("%s\n", len);
return 0;
}
char* my_strstr(char* str1, char* str2)
{
char* cp = str1;
char* s1 = cp;
char* s2 = str2;
if (*str2 == '\0')
{
return str1;
}
while (*cp)
{
s1 = cp;
s2 = str2;
while (*s1 && *s2 && *s1 == *s2)
{
s1++;
s2++;
}
if (*s2 == '\0')
return cp;
cp++;
}
return NULL;
}
int main()
{
char arr1[] = "abbbcdef";
char arr2[] = "bbc";
char* len = my_strstr(arr1, arr2);
if (len != NULL)
{
printf("%s\n", len);
}
else
printf("找不到\n");
return 0;
}
cp:从这个位置开始打印的参数;
s1、s2:两个用来匹配两个字符串是否有相同子字符串的参数;
cp、s1从str1的首字符开始,s2从str2的首字符开始,在匹配之前先判断str2是否为空,如果是,则返回str1(直接打印arr1)。cp是开始打印的起始位置,如果它遍历完(遇到斜杠0,则返回空,找不到),如果不为斜杠0,进入第一层循环,把此时的cp的位置赋给s1,s2再刷新到str2的首字符位置,进入第二层循环,如果s1不为0,s2,不为0,并且两个相等,则s1和s2的地址++;如果s1与s2不相等了,跳出第二层循环,cp地址++,然后再进入第一层循环,把地址+1后的cp赋给s1,s2又刷新到str2首字符的位置,重复上面的过程,如果s1为0,则返回空,找不到;如果s2为0,说明已经找到了,返回cp的地址,然后开始打印的位置就从cp的地址开始打印str1。
char * strtok ( char * str, const char * sep )
总结以下几点:
sep参数是个字符串,定义了用作分隔符的字符集合
第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记
strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。(注:strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。)
strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。
strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记。
如果字符串中不存在更多的标记,则返回 NULL 指针。
strtok函数的使用:
int main()
{
char arr[] = "abcd#efg.hi@789";
char copy[30];
strcpy(copy, arr);
char sep[] = "#.@";
char* len = NULL;
for (len = strtok(copy, sep); len != NULL; len = strtok(NULL, sep))
{
printf("%s\n", len);
}
return 0;
}
strerror函数的作用是返回错误码,所对应的错误信息。
库函数在执行的时候,如果发生了错误,会将一个错误码存放在errno这个变量中,errno是全局变量。
#include
int main()
{
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%d: %s\n", i, strerror(i));
}
return 0;
}
函数 如果他的参数符合下列条件就返回真
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 任何可打印字符,包括图形字符和空白字符
int tolower ( int c );
功能:把大写字母字符转换成小写,非大写字母字符不做处理,头文件是
int toupper ( int c );
功能:把小写字母转换成大写,非小写字母字符不做处理,头文件是