字符串函数及其实现
1.字符串函数介绍
1.1 strlen
strlen函数是求字符串长度的函数
size_t strlen ( const char * str );
strlen的注意事项
?1.字符串已经 ‘\0’ 作为结束标志,strlen函数返回的是在字符串中 ‘\0’ 前面出现的字符个数(不包含 ‘\0’ )。 ?如下图所示,字符串中已经包含了\0
?2.参数指向的字符串必须要以 ‘\0’ 结束
//arr中没有以\0结尾,打印出来的长度就有问题
int main() {
//char arr[] = "abc";
char arr[] = { 'a','b','c' };
int len=strlen(arr);
printf("%d", len);
}
3.注意函数的返回值为size_t,是无符号的
//size_t是一个无符号整数,这里虽然减出来是小于0的,但是作为无符号整数没有符号位,就大于0了
int main() {
if ((strlen("abc") - strlen("abcd"))>0) {
printf(">");
}else {
printf("<=");
}
}
4.strlen函数的模拟实现
1.计数器版本
int my_strlen(const char* str) {
int count = 0;
assert(str);
while (*str!='\0') {
count++;
str++;
}
return count;
}
2.指针减指针版本
int my_strlen(const char* str) {
char* p = str;
while (*p != '\0') {
p++;
}
return p - str;
}
3.递归版本
int my_strlen(const char* str) {
if (*str == '\0') {
return 0;
}
else {
return 1 + my_strlen(str + 1);
}
}
1.2 strcpy
strcpy是字符串长度不限制的函数,它把含有’\0’结束符的字符串复制到另一个地址空间
char* strcpy(char * destination, const char * source );
source是要复制的源字符串指针 destination是存储复制内容的目标指针 也就是说destination会拷贝source的值,把destination原本的值覆盖。
int main() {
char arr[20] = "abc";
char* p = "hello";
strcpy(arr, p);
printf("%s", arr);
}
strcpy注意事项:
1.源字符串必须以 ‘\0’ 结束 2.会将源字符串中的 ‘\0’ 拷贝到目标空间。
3.目标空间必须足够大,以确保能存放源字符串
arr开辟的空间不够大,发生发错。 4.目标空间必须可变
2.strcpy模拟实现
char* my_strcpy(char* dest, const char* src) {
char* ret = dest;
while (*dest++ = *src++) {
;
}
return ret;
}
1.3 strcat
strcat是字符串追加函数
char * strcat ( char * destination, const char * source );
int main() {
char arr[20] = "hello ";
char* p = "world";
strcat(arr, p);
printf("%s", arr);
}
strcat注意事项: 1.源字符串必须以 ‘\0’ 结束 2.目标空间必须有足够的大,能容纳下源字符串的内容。 3.目标空间必须可修改。 4.字符串不能自己给自己追加,会把原先自己的\0标志覆盖
strcat模拟实现
char* my_strcat(char* dest, const char* src) {
char* ret = dest;
while (*dest != '\0') {
dest++;
}
while (*dest++ = *src++) {
;
}
return ret;
}
1.4 strcmp
int strcmp ( const char * str1, const char * str2 );
标准规定: 第一个字符串大于第二个字符串,则返回大于0的数字 第一个字符串等于第二个字符串,则返回0 第一个字符串小于第二个字符串,则返回小于0的数字
两个字符串自左向右逐个字符相比(按ASCII值大小相比较),直到出现不同的字符或遇'\0'为止
1."A"<"B" 2."A"<"AB" 3."Apple"<"Banana" 4."A"<"a" 5."compare"<"computer"
strcmp函数实现
int my_strcmp(const char* s1, const char* s2) {
assert(s1 && s2);
while (*s1 == *s2) {
if (*s1 == '\0') {
return 0;
}
s1++;
s2++;
}
return *s1-*s2
}
1.5 strncat
?把src所指字符串的前n个字符添加到dest所指字符串的结尾处,并覆盖dest所指字符串结尾的’\0’,从而实现字符串的连接
char * strncat ( char * destination, const char * source, size_t num );
int main ()
{
char str1[20]="world";
strncpy(str1, "hello",3);
puts(str1);
return 0;
}
1.6 strncmp
int strncmp ( const char * str1, const char * str2, size_t num ) 把 str1 和 str2 进行比较,最多比较前 n 个字节
int strncmp ( const char * str1, const char * str2, size_t num )
str1 -- 要进行比较的第一个字符串。
str2 -- 要进行比较的第二个字符串。
n -- 要比较的最大字符数。
如果返回值 < 0,则表示 str1 小于 str2。
如果返回值 > 0,则表示 str1 大于 str2。
如果返回值 = 0,则表示 str1 等于 str2。
char str1[15]="abcd";
char str2[15]="ABCD";
int ret;
ret = strncmp(str1, str2, 4);
if (ret < 0)
{
printf("str1 小于 str2");
}
else if (ret > 0)
{
printf("str2 小于 str1");
}
else
{
printf("str1 等于 str2");
}
return 0;
1.8 strstr
在字符串str1中查找第一次出现字符串 str2的位置,不包含终止符 ‘\0’,如果未找到则返回 null
char * strstr ( const char *str1, const char * str2);
char* my_strstr(const char* str1, const char* str2)
{
char* cp = (char*)str1;
char* s1, * s2;
if (!*str2)
return((char*)str1);
while (*cp)
{
s1 = cp;
s2 = (char*)str2;
while (*s1 && *s2 && !(*s1 - *s2))
s1++, s2++;
if (!*s2)
return(cp);
cp++;
}
return(NULL);
}
1.9 strtok
char * strtok ( char * str, const char * sep );
sep参数是个字符串,定义了用作分隔符的字符集合。
str是一个一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记
如果要想把一个邮箱分割开,比如baidu@qq.com 分割符是@和.,通过这两个分割符获取baidu和qq和com strtok注意事项 ?1.sep参数是个字符串,定义了用作分隔符的字符集合 ?2.第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记。 ?3.strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。例如上面的baidu@qq.com,找到分割符@后,会把@变为\0,这样在打印的时候就会打印出baidu ?4.strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。 ?5.strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置, ?例如上面的baidu@qq.com,找到第一个分割符@后,会把@变为\0,这样在打印的时候就会打印出baidu ?6.strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记。 ?例如上面baidu@qq.com找到第一个分割符@后,会把@变为\0,如果我再次调用函数,里面的参数写成NULL,函数就会从原先@变为\0的位置开始向后查找下一个分割符
strtok函数在初次调用时,把str,sep传过去,之后想要再次调用时,传入NULL即可。
strtok模拟实现
int main() {
char arr[20] = "baidu@qq.com";
char* p = "@.";
char str[20] = { 0 };
char* s=strcpy(str, arr);
for (s = strtok(arr, p); s!= NULL; s= strtok(NULL, p))
{
printf("%s\n", s);
}
}
1.10 strerror
返回错误码,所对应的错误信息
char * strerror ( int errnum );
FILE* pFile;
pFile = fopen("unexist.ent", "r");
if (pFile == NULL){
printf("Error opening file unexist.ent: %s\n", strerror(errno));
}
|