订阅
以下专栏。C语言中对字符和字符串的处理很是频繁,不仅如此在以后的校招面试中字符串的题目也会涉及不少,这点在LeetCode中就能体现到,在刷题时经常会遇到处理字符串的内容,字符串还和指针相关联,对字符串的深入理解也会增加对指针的理解。
❄️功能:求字符串长度
❄️函数原型
size_t strlen ( const char* str );
注意:
size_t
,是无符号整型,也就是不是负数。( 易错!!!
)1.指针-指针的方式
注意:这种方式只适用于同一个数组
int my_strlen(char *s)
{
char *p = s;
while(*p != ‘\0’ )
p++;
return p-s;
}
2.计数器方法
int my_strlen(const char* str)
{
int count = 0;
while(*str)
{
count++;
str++;
}
return count;
}
3.递归方法(面试官最爱考
)
//不能创建临时变量计数器
int my_strlen(const char * str)
{
if(*str == '\0')
return 0;
else
return 1+my_strlen(str+1);
}
❄️函数功能:拷贝源字符串到目的地空间,包括"\0"也拷贝过去
。
❄️函数原型
char *strcpy( char *strDestination, const char *strSource );
注意:
原字符串不可变!
注意点:
char *my_strcpy(char *dest, const char*src)
{
char *ret = dest;
assert(dest != NULL);
assert(src != NULL);
while((*dest++ = *src++))
{
;
}
return ret;
}
❄️函数功能:
❄️函数原型
char * strcat ( char * destination, const char * source );
注意:
注意:
后置++是先使用后++。
char *my_strcat(char *dest, const char*src)
{
char *ret = dest;
assert(dest != NULL);
assert(src != NULL);
while(*dest)
{
dest++;
}
while((*dest++ = *src++))
{
;
}
return ret;
}
❄️函数功能:
❄️函数原型
char * strncpy ( char * destination, const char * source, size_t num );
注意:
并不是大于返回1,小于返回-1,没有这个规定
规定如下
注意;
while的循环条件&&操作符,左操作数为假时,有操作数就不用执行了。
int my_strcmp (const char * src, const char * dst)
{
int ret = 0 ;
assert(src != NULL);
assert(dest != NULL);
while( ! (ret = *(unsigned char *)src- *(unsigned char *)dst) && *dst)
{
++src;
++dst;
}
if ( ret < 0 )
ret = -1 ;
else if ( ret > 0 )
ret = 1 ;
return( ret );
}
❄️函数功能:
拷贝num个字符从源字符串到目标空间。
❄️函数原型
char * strncpy ( char * destination, const char * source, size_t num );
注意:
❄️函数功能:
将num个源字符串和目标字符串连接起来。
❄️函数原型
char * strncat ( char * destination, const char * source, size_t num );
注意:
函数功能:
在目标字符串str1里找到源字符串,并返回这个源字符串的首元素的地址。
函数原型
char * strstr ( const char *str1, const char * str2);
注意:
如图包含了找字符串的所有情况。
思考问题要考虑全面。
我认为下面代码是最优的代码了。但是需要自己细看
。描述的话太麻烦了。
#include
#include
char* my_strstr(const char* str1, const char* str2)
{
assert(str1 && str2);
if (!*str2)
{
return((char*)str1);
}
char* cp = str1;
char* s1 = 0;
char* s2 = 0;
while (*cp != '\0')
{
s1 = cp;
s2 = str2;
while (*s2 != '\0' && *s1 != '\0' && *s2 == *s1)
{
s1++;
s2++;
if (!*s2)
{
return cp;
}
}
cp++;
}
return NULL;
}
int main()
{
char arr[] = "hworld";
char arr1[] = "world";
char* p = my_strstr(arr, arr1);
printf("%s", p);
return 0;
}
❄️函数功能:将字符串分割。
❄️函数原型
char * strtok ( char * str, const char * sep );
注意
❄️函数功能:返回错误码所对应的错误信息。
❄️函数原型
char * strerror ( int errnum );
例子
/* strerror example : error list */
#include
#include
#include //必须包含的头文件
int main ()
{
FILE * pFile;
pFile = fopen ("unexist.ent","r");
if (pFile == NULL)
printf ("Error opening file unexist.ent: %s\n",strerror(errno));
//errno: Last error number
return 0;
}
Edit & Run
函数 | 如果他的参数符合下列条件就返回真 |
---|---|
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 | 任何可打印字符,包括图形字符和空白字符 |
iscntrl | 任何控制字符 |
❄️函数功能:
❄️函数原型
void * memcpy ( void * destination, const void * source, size_t num );
注意:
进行强制类型转换
。void * memcpy ( void * dst, const void * src, size_t count)
{
void * ret = dst;
assert(dst);
assert(src);
while (count--)
{
*(char *)dst = *(char *)src;
dst = (char *)dst + 1;
src = (char *)src + 1;
}
return(ret);
}
❄️函数功能:
❄️函数原型
void * memmove ( void * destination, const void * source, size_t num );
注意:
重叠
,就得使用memmove函数处理。注意
前往后拷贝
就可以了从后往前拷贝
void* memmove(void* dst, const void* src, size_t count)
{
void* ret = dst;
if (dst <= src || (char*)dst >= ((char*)src + count))
{
while (count--)
{
*(char*)dst = *(char*)src;
dst = (char*)dst + 1;
src = (char*)src + 1;
}
}
else
{
dst = (char*)dst + count - 1;
src = (char*)src + count - 1;
while (count--)
{
*(char*)dst = *(char*)src;
dst = (char*)dst - 1;
src = (char*)src - 1;
}
}
return(ret);
}
❄️函数功能:
❄️函数原型
int memcmp ( const void * ptr1,
const void * ptr2,
size_t num );
函数返回值