本节小编将讲解一下相关字符串函数的使用和模拟,干货满满!!!
重点介绍处理字符和字符串的库函数的使用和注意事项
一.相关函数分类
1.求字符串长度
strlen
2.长度不受限制的字符串函数
strcpy strcat strcmp
3.长度受限制的字符串函数介绍
strncpy strncat strncmp
4.字符串查找
strstr strtok
5.错误信息报告
strerror
前言
C语言中对字符和字符串的处理很是频繁,但是C语言本身是没有字符串类型的,字符串通常放在常量字符串中或者字符数组中。
字符串常量 适用于那些对它不做修改的字符串函数.
二. 函数介绍
2.1 strlen 长度计算
1.字符串已经 '\0' 作为结束标志,strlen函数返回的是在字符串中 '\0' 前面出现的字符个数(不包含 '\0' )。
#include <stdio.h> include <string.h> int main(){ char arr[]="abcdef";//abcdef\0 int len=strlen(arr); printf("%d",len); return 0; } 结果:6
2.参数指向的字符串必须要以 '\0' 结束。
#include <stdio.h> include <string.h> int main(){ char arr[]={'b','i','t'};// int len=strlen(arr); printf("%d",len); return 0; } 运行结果为随机值
3.注意函数的返回值为size_t,是无符号的( 易错 )
//size_t strlen ( const char * str );C //size_t 为无符号整型 #include <stdio.h> #include <string.h> int main(){ const char*str1 = "abcdef"; const char*str2 = "bbb"; if(strlen(str2)-strlen(str1)>0) { printf("str2>str1\n"); } else { printf("srt1>str2\n"); } return 0; } 运行结果:str2>str1
strlen返回的是无符号整型,两个无符号整型 运算结果还是无符号整型,尽管相减是-3,但是当做无符号整型处理,存到内存的补码将会当成正数。可以直接进行比较或者强制转换类型。
学会strlen函数的模拟实现
计数器
#include <stdio.h> #include <string.h> #include <assert.h> #define N 100 int my_strlen(const char *str) { int count = 0; assert(str); while (*str != '\0') { count++; str++; } return count; } int main() { char arr[N] = {0}; printf("输入字符串:\n"); scanf("%s", arr); int n = my_strlen(arr); printf("%d\n", n); return 0; } int main(){ char ch[N]; //printf("请输入字符串:\n"); gets(ch); printf("%d\n",mystrlen(ch)); return 0; } int mystrlen(const char str[ ]) { int i ; int len = 0; //计数器置0 for (i=0; str[i]!='\0'; i++) { len++; } return len; }
指针-指针(也可计算长度)
#include <stdio.h> #define N 100 int my_strlen(char *s) { char *p = s; while (*p != '\0') p++; return p - s; } int main() { char str[N] ={0}; scanf ("%s",str); int length = my_strlen(str); printf("字符串长度:%d\n", length); return 0; }
补充知识:assert断言
assert
是C语言中的一个宏定义,用于在程序中进行断言(assertion)。它的作用是在代码中插入一条断言条件,用于检查某个表达式的结果是否为真。如果断言条件为假,即表达式结果为0,则会触发断言错误。
assert
宏的语法如下:
#include
void assert(int expression);
其中,expression
是一个要进行断言的条件表达式,通常是一个返回布尔值的表达式。如果expression
为假(即0),assert
宏会触发断言错误。
断言错误的输出通常包含了触发断言的源文件、行号以及一条错误消息。断言错误通常会导致程序终止执行,以帮助开发者快速发现并定位问题。
assert
的主要用途是在开发和调试阶段进行错误处理和调试信息的输出。通过合理地使用断言,我们可以在代码中插入一些逻辑检查点,确保程序在正确的条件下执行,同时帮助发现和修复潜在的问题。
需要注意的是,断言通常在开发过程中使用,在发布版本中会被禁用。这是因为断言仅用于开发和调试,而不应该成为生产代码中的错误处理机制。
示例用法:
#include <stdio.h> #include <assert.h> int main() { int x = 10; assert(x > 0); // 断言x大于0 printf("断言通过\n"); int y = 0; assert(y != 0); // 断言y不等于0 printf("这行代码不会被执行\n"); return 0; }
在上述示例中,第一个断言 assert(x > 0);
是正确的,因此程序会输出 "断言通过"。而第二个断言 assert(y != 0);
是错误的,因为y等于0,所以会触发断言错误,并终止程序的执行。
2.2 strcpy 拷贝
Copies the C string pointed by source into the array pointed by destination, including the
terminating null character (and stopping at that point).
源字符串必须以 '\0' 结束。会将源字符串中的 '\0' 拷贝到目标空间。目标空间必须足够大,以确保能存放源字符串。目标空间必须可变。
学会模拟实现。
char* strcpy(char * destination, const char * source );
错误用法
int main(){ const char*p="abcdef"; char arr[]="bit"; strcpy(p,arr);//error 目标区域不可修改,常量字符串 return 0; }
模拟实现
#include <stdio.h> #include <string.h> #include <assert.h> char* my_strcpy(char* p1, const char* p2) { assert(p1); //如果为空指针,则报错 assert(p2); char* ret = p1; while ((*p1++ = *p2++)) { } return ret; } int main() { char arr1[100] = {0}; char arr2[100] = {0}; // 修改为合适的大小,以避免缓冲区溢出 printf("输入字符串:"); scanf("%s", arr2); my_strcpy(arr1, arr2); printf("%s\n", arr1); // 打印复制后的字符串 return 0; }
2.3 strcat 字符串追加
char* strcat(char * destination, const char * source );
源字符串必须以 '\0' 结束。目标空间必须有足够的大,能容纳下源字符串的内容。目标空间必须可修改。
字符串自己给自己追加,如何?不能,会破坏原字符串。
模拟实现
#include <stdio.h> #include <string.h> #include <assert.h> char *my_strcat(char *dest, const char*src) { char *ret = dest; assert(dest != NULL); assert(src != NULL); //寻找\0 while(*dest)//while(*dest !='\0') { dest++; } while((*dest++ = *src++)){ ; } return ret; } int main(){ char arr1[]="I love "; char arr2[100]={0}; scanf("%s",arr2); my_strcat(arr1, arr2); printf("%s\n", arr1); // 打印追加后的字符串 return 0; }
2.4 strcmp 字符串比较
字符串的字典序比较是指按照字典(词典)的排序方式来比较字符串的大小。在字典序中,字符串按照字符的 ASCII 值的顺序进行比较。
具体来说,对于两个字符串进行字典序比较时,从左到右逐个比较对应位置上的字符的 ASCII 值。如果两个字符相同,则继续向后比较下一个字符,直到遇到不同的字符,或者至少其中一个字符串结束。
int strcmp ( const char * str1, const char * str2 );
标准规定
第一个字符串大于第二个字符串,则返回大于0的数字
第一个字符串等于第二个字符串,则返回0
第一个字符串小于第二个字符串,则返回小于0的数字
那么如何判断两个字符串?
模拟实现
#include <stdio.h> #include <string.h> //#include <assert.h> int my_strcmp(char *str1, char*str2){ while(*str1==*str2){ if(*str1=='\0') return 0; str1++; str2++; } if (*str1>*str2) //这几行也可以直接替换成 return(*str1-*str2); return 1; else return -1; } int main(){ char str1[100]={0}; char str2[100]={0}; printf("请输入字符串\n"); scanf("%s",str1); scanf("%s",str2); int ret=my_strcmp(str1,str2); if (ret==0) printf("=\n"); else if(ret>0) printf(">\n"); else printf("<"); return 0; }
以下三个函数第三个参数控制了字符个数
2.5 strncpy
char * strncpy ( char * destination, const char * source, size_t num );
拷贝num个字符从源字符串到目标空间。
如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加\0,直到num个。
#include <stdio.h> #include <string.h> int main(){ char dest[20] = "Hello"; char src[] = " World"; strncat(dest, src, 6); printf("%s", dest); // Output: Hello World return 0; }
2.6 strncat
追加num个字符从源字符串到目标空间。
char * strncat ( char * destination, const char * source, size_t num );
#include <stdio.h> #include <string.h> int main () { char str1[20]; char str2[20]; strcpy (str1,"To be "); strcpy (str2,"or not to be"); strncat (str1, str2, 6); //puts (str1); printf ("%s\n",str1); return 0; }
运行结果:To be or not
字符串函数详解(看这一篇就足够了)(下):https://developer.aliyun.com/article/1624350