字符串操作函数
字符串长度
strlen
strlen的模拟实现有三种不同的方法,分别是:递归,定义计数器的循环和指针相减
递归
#include <stdio.h>
#include <assert.h>
int myStrlen(const char* str){
assert(str);
if(*str=='\0') return 0;
else return 1+myStrlen(str+1);
}
int main(){
char str[]="abcdefg";
printf("%d\n",myStrlen(str));
return 0;
}
定义计数器的循环
#include <stdio.h>
#include <assert.h>
int myStrlen(const char* str){
assert(str);
int count=0;
while(*str) {
str++;
count++;
}
return count;
}
int main(){
char str[]="abcdefg";
printf("%d\n",myStrlen(str));
return 0;
}
指针相减
#include <stdio.h>
#include <assert.h>
int myStrlen(const char* str){
assert(str);
char* start=str;
while(*str) str++;
return str-start;
}
int main(){
char str[]="abcdefg";
printf("%d\n",myStrlen(str));
return 0;
}
!!!
注意:
在模拟实现库函数的开头应该先判断并处理特殊情况,如利用assert检查传进来的指针是否为空指针或考虑当传进来的字符串长度为0时是否特殊处理。
当传进来的参数不会被改变时,记得加上const保护字符串不被修改,提高安全性。
长度不受限制的字符串函数
strcpy
#include <stdio.h>
#include <assert.h>
char* myStrcpy(char* dest, const char* src) {
assert(dest && src);
char* ret = dest;
while (*dest++ = *src++);
return ret;
}
int main() {
char d[100] = "xxxxxxxxxxxxxxxxxxxxxxxx";
char s[] = "abcdefg";
printf("%s\n", myStrcpy(d, s));
return 0;
}
strcat
#include <stdio.h>
#include <assert.h>
char* myStrcat(char* dest, const char* src) {
assert(dest && src);
char* ret = dest;
while(*dest) dest++;
while (*dest++ = *src++);
return ret;
}
int main() {
char d[100] = "xxxxxxxx";
char s[] = "abcdefg";
printf("%s\n", myStrcat(d, s));
return 0;
}
strcmp
1.返回值为1,0,-1(同vs)
#include <stdio.h>
#include <assert.h>
int myStrcmp(const char* s1, const char* s2) {
assert(s1 && s2);
while ((*s1 == *s2) && *s1 && *s2) {
s1++;
s2++;
}
if(*s1 == *s2) return 0;
else if(*s1 > *s2) return 1;
else if(*s1 < *s2) return -1;
}
int main() {
char s1[] = "abcdefg";
char s2[] = "abcdefg";
printf("%d\n", myStrcmp(s1, s2));
return 0;
}
返回值为正数,0,负数
#include <stdio.h>
#include <assert.h>
int myStrcmp(const char* s1, const char* s2) {
assert(s1 && s2);
while ((*s1 == *s2) && *s1 && *s2) {
s1++;
s2++;
}
return *s1 - *s2;
}
int main() {
char s1[] = "abcdef";
char s2[] = "abcde";
printf("%d\n", myStrcmp(s1, s2));
return 0;
}
长度受限制的字符串函数
strncpy
#include <stdio.h>
#include <assert.h>
char* myStrncpy(char* dest, const char* src, size_t num) {
assert(dest && src&&(num>=0));
char* ret = dest;
while (*src && (num > 0)) {
*dest++ = *src++;
num--;
}
while (num > 0) {
*dest = '\0';
dest++;
num--;
}
return ret;
}
int main() {
char d[] = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
char s[] = "hello world";
printf("myStrncpy %s\n", myStrncpy(d, s, 3));
printf("myStrncpy %s\n", myStrncpy(d, s, 6));
printf("myStrncpy %s\n", myStrncpy(d, s, 11));
printf("myStrncpy %s\n", myStrncpy(d, s, 16));
return 0;
}
strncat
#include <stdio.h>
#include <assert.h>
char* myStrncat(char* dest, const char* src, size_t num) {
assert(dest && src && (num>=0));
char* ret = dest;
while (*dest) dest++;
while (*src && (num > 0)) {
*dest++ = *src++;
num--;
}
while (num > 0) {
*dest++= '\0';
num--;
}
return ret;
}
int main() {
char d[100] = "xxxxxxxxxxxx";
char s[] = "hello world";
printf("myStrncat %s\n", myStrncat(d, s, 10));
return 0;
}
strncmp
#include <stdio.h>
#include <assert.h>
int myStrncmp(const char* s1, const char* s2, size_t num) {
assert(s1 && s2);
while (--num && *s1 && *s2) {
if (*s1 != *s2) break;
else s1++,s2++;
}
return *s1 - *s2;
}
int main() {
char s1[] = "abcdef";
char s2[] = "abcde";
printf("%d\n", myStrncmp(s1, s2, 6));
printf("%d\n", myStrncmp(s1, s2, 5));
return 0;
}
字符串查找
strstr(暴力解法)
#include <stdio.h>
#include <assert.h>
char* myStrstr(const char* dad, const char* son) {
assert(dad && son);
if (*son == '\0') return dad;
char* pd = dad;
char* ps = son;
char* stay = dad;
while (*pd) {
pd = stay;
ps = son;
while ((*pd == *ps)&&*pd&&*ps) {
pd++,ps++;
}
if (*ps == '\0') return stay;
stay++;
}
return NULL;
}
int main() {
char d[]="abcabcabcd";
char s[]="cabcd";
printf("%s\n", myStrstr(d, s));
return 0;
}
内存操作函数
memcpy
#include <stdio.h>
#include <assert.h>
void* myMemcpy(void* dest, const void* src, size_t num) {
assert(dest && src&&(num>=0));
void* ret = dest;
while (num>0) {
*(char*)dest = *(char*)src;
((char*)dest)++;
((char*)src)++;
num--;
}
return ret;
}
int main() {
int d[100] = { 0 },num=32;
int s[] = { 1,2,8,9,0,5,4,4,2,9 };
myMemcpy(d, s, num);
for (int i = 0; i < 10; i++) {
printf("%d ", d[i]);
}
return 0;
}
memmove
#include <stdio.h>
#include <assert.h>
void* myMemmove(void* dest, const void* src, size_t num) {
assert(dest && src );
void* ret = dest;
//情况1 dest<src 前-后
if ((char*)dest < (char*)src) {
for(int i=0;i<num;i++){
*((char*)dest + i) = *((char*)src + i);
}
}
//情况2 dest>src 后-前
else {
for (int i = num-1; i >=0; i--) {
*((char*)dest + i) = *((char*)src + i);
}
}
return ret;
}
int main() {
int d[100] = { 0 }, num = 16;
int s[] = { 1,2,8,9,0,5,4,4,2,9 };
myMemmove(s+4, s+1, num);
for (int i = 0; i < sizeof(s) / sizeof(s[0]); i++) {
printf("%d ", s[i]);
}
printf("\n");
myMemmove(s, s + 5, num);
for (int i = 0; i < sizeof(s)/sizeof(s[0]); i++) {
printf("%d ", s[i]);
}
return 0;
}
memcmp
#include <stdio.h>
#include <assert.h>
#include <string.h>
int myMemcmp(const void* ptr1, const void* ptr2, size_t num) {
assert(ptr1 && ptr2);
while (--num) {
if (*((char*)ptr1) == *((char*)ptr2)) {
ptr1 = (char*)ptr1 + 1;
ptr2 = (char*)ptr2 + 1;
}
}
return *(char*)ptr1 - *(char*)ptr2;
}
int main() {
int d[100] = { 0 };
int arr[] = { 1,2,90,9,0,5,4,4,1,9 };
int arr1[] = { 1,2,8,9,0,5,4,4,1,9 };
int arr2[] = { 1,2,8,9,0,5,4,4,2,9 };
int arr3[] = { 1,2,8,9,0,5,4,4,2,8 };
printf("%d\n", myMemcmp(arr, arr2, 240));
printf("%d\n", myMemcmp(arr1, arr2, 24));
printf("%d\n", myMemcmp(arr1, arr2, 240));
printf("%d\n", myMemcmp(arr3, arr2, 36));
return 0;
}