本文重点:
1.求字符串长度:strlen
2.长度不受限制的字符串函数: strcpy , strcat , syrcmp
3.长度受限制的字符串函数:strncpy , strncat , strncmp
4.字符串查找:strstr , strtok
5.错误信息报告:strerror
6.内存操作函数:memcpy , memmove , memset , memcmp
在C语言中对字符和字符串的处理很是频繁,但是C语言本身是没有字符串类型的,字符串通常放在 常量字符串中或者字符数组中。字符串常量适用于那些对它不做修改的字符串函数。
一.关于字符串函数的分类和模拟实现:
1.strlen(求字符串长度)
size_t strlen ( const char * str );
//注意其中size_t表示返回值是一个无符号的长整型;
//其中const 指其指向的内容不能进行修改;
注意:
字符串已经 ‘\0’ 作为结束标志,strlen函数返回的是在字符串中 ‘\0’ 前面出现的字符个数(不包含 \0’)。 参数指向的字符串必须要以 ‘\0’ 结束。
注意函数的返回值为size_t,是无符号的( 易错 )
关于strlen函数的模拟实现:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
size_t strlen(const char* str){
assert(str!=NULL);
size_t count=0;
while(str[i]!='\0'){
count++;
}
return count;
}
int main(){
char str[]="hehe";
char* p=str;
if(p!='\0'){
printf("%lu\n",strlen(p));
}
system("pause");
return 0;
}
2.strcpy(字符串拷贝)
char* strcpy(char * destination, const char * source );
注意:字符串只能使用 = 初始化,不能使用 = 赋值;
实现:
(1)会将源字符串中的 ‘\0’ 拷贝到目标空间。
(2)目标空间必须足够大,以确保能存放源字符串。
(3)目标空间必须可变。
关于strcpy函数的模拟实现:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
char* strcpy(char *dest,char* src){
assert(dest!=NULL);
assert(src!=NULL);
for(int i=0;dest[i]!='\0';i++){
dest[i]=src[i];
}
dest[i]='\0';
return 0;
}
int main(){
char dest[]="hehehe";
strcpy(dest,"haha");
printf("%s\n",dest);
system("pause");
return 0;
}
3.strcat(字符串拼接)
char * strcat ( char * destination, const char * source );
源字符串必须以 ‘\0’ 结束;
目标空间必须有足够的大,能容纳下源字符串的内容;
目标空间必须可修改;
关于strcat函数的模拟实现:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
char* strcat(char* dest,char* src){
assert(dest!=NUL);
assert(src!=NULL);
for(int i=0;dest[i]!='\0';i++);
for(int j=0;src[j]!='\0';i++,j++){
dest[i]=src[j];
}
dest[i]='\0';
return dest;
}
int main(){
char dest[1024]="hehehe";
strcat(dest,"hahaha");
printf("%s\n",dest);
system("pause");
return 0;
}
4.strcmp(字符串比较)
int strcmp ( const char * str1, const char * str2 );
标准规定:
第一个字符串大于第二个字符串,则返回大于0的数字;
第一个字符串等于第二个字符串,则返回0;
第一个字符串小于第二个字符串,则返回小于0的数字;
关于strcmp函数的模拟实现:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
int strcmp(const char* str1,const char* str2){
assert(str1!=NULL);
assert(str2!=NULL);
while(*str1!='\0' && *str2!='\0'){
if(*str1>*str2){
return 1;
}
if(*str1<str2){
return -1;
}
else{
++str1;
++str2;
}
}
if(*str1=='\0' && *str2!='\0'){
return -1;
}
else if(*str1!='\0' && *str2=='\0'){
return 1;
}
else if(*str1=='\0' && *str2!='\0'){
return 0;
}
}
int main(){
char str1[]="hahahaha";
char str2[]="hehehe";
int ret=strcmp(str1,str2);
if(ret<0){
printf("小于\n");
}else if(ret==0){
printf("等于\n");
}else if(ret>0){
printf("大于\n");
}
system("pause");
return 0;
}
5.strstr(字符串查找)
char * strstr ( const char *str1, const char *str2 );
关于strstr函数的模拟实现:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
char* strstr(const char* str1,const char* str2){
assert(str1!=NULL);
assert(str2!=NULL);
if(*str1=='\0' && *str2=='\0'){
return NULL;
}
const char* black_ptr=str1;
while(*black_ptr!='\0'){
const char* sub_ptr=str2;
const char*red_ptr=black_ptr;
while ( * red_ptr !='\0' && * sub_ptr!='\0' && (*red_ptr==*sub_ptr)) {
++sub_ptr;
++red_ptr;
}
if (* sub_ptr=='\0') {
//说明已经找到了子字符串;
return black_ptr;
}
++black_ptr;
}
return NULL;
}
二.关于内存函数介绍及模拟实现:
1.memcpy(字符串拷贝函数)
void * memcpy ( void * destination, const void * source, size_t num );
(1)这个函数在遇到 '\0' 的时候并不会停下来。
(2)如果source和destination有任何的重叠,复制的结果都是未定义的。
功能:
由src指向地址为起始地址的连续n个字节的数据复制到以dest指向地址为起始地址的空间内。
关于memcpy函数的模拟实现:
#include<stdlib.h>
#include<string.h>
#include<assert.h>
void * Memcpy (void* dest ,const void* src, size_t num) {
assert (dest!= NULL);
assert (src!=NULL);
char *pdest= (char* ) dest;
char * psrc=(char* )src;
for (size_t=i; i<num;++i) {
pdest[i]=psrc[i];
}
return dest;
}
int main( ) {
int arr1[4] ={1,2,3,4};
int arr2[4] ={0};
memcpy (arr2, arr1, sizeof(arr1));
for ( int i=0; i<4; ++i) {
printf ( "%d\n", arr2[i]);
}
system("pause");
return 0;
}