C语言面试题分类->字符串处理
1.strlen:计算字符串长度(不包含'\0')
实现想法:遍历字符串,直到'\0'结束
#include<stdio.h> #include<stdlib.h> #include<string.h> //指针法 unsigned int mystrlenaddr(const char * str) //为什么使用const char,我们只计数不对原数据进行改变 { int length = 0; //长度初始化为0 while (*str++) { length++; } return length; } void main() { char * str = "fengcong is fucking too handsome"; //32个 //printf("%d\n", strlen(str)); printf("%d\n", mystrlenaddr(str)); system("pause"); }
2.strcmp:比较字符串大小(一般用于字符串排序)
实现想法:依次从字符串开始一直找到不同的那个字符进行比较,得出大小
#include<string.h> #include<stdio.h> #include<stdlib.h> //掌握指针法 int mystrcmp(char const * str1, const char * str2) { while (*str1 == *str2 && *str1 != '0') //一直找到两个字符串不同的地方 { str1++; str2++; } if (*str1 > *str2) return 1; else if (*str1 < *str2) return -1; else return 0; } void main() { char * str = "feng1"; char * str1 = "feng2"; //printf("%d\n", strcmp(str, str1)); printf("%d\n", mystrcmp(str, str1)); system("pause"); }
3.strcpy:用于字符串复制(复制包含'\0')
实现想法:一直复制到'\0'结束
#define _CRT_SECURE_NO_WARNINGS #include<stdlib.h> #include<stdio.h> #include<string.h> //指针法 char * mystrcpyaddr(char * dest, const char * source) { if (dest == NULL || source == NULL) { return NULL; //如果目的操作或者源为空,那么久直接返回 } while (*dest++ = *source++) //装X写法 ; return dest; } //下标法 char * mystrcpyindex(char * dest, const char * source) { if (dest == NULL || source == NULL) { return NULL; //如果目的操作或者源为空,那么久直接返回 } int i = 0; while (source != '\0') { dest = source; i++; } dest = source; //因为要把最后的\0拷贝过去 return dest; } void main() { char * str = "fengcong is fucking too handsome"; char str1[100]; //目的字符数组 //strcpy(str1, str); //printf("%s\n", str1); mystrcpyindex(str1, str); printf("%s\n", str1); system("pause"); }
4.strstr:寻找母串中是否存在某个子串(稍难)
实现想法:依次比对
#include<stdio.h> #include<stdlib.h> #include<string.h> //下标 法 char * mystrstrindex(char * const momstr, const char * const sonstr)//前者指针指向的数据可变,但是指针不可变,后者都不可变 { int momlen = strlen(momstr); //母串的长度 int sonlen = strlen(sonstr); //子串的长度 for (int i = 0; i < (momlen - sonlen); i++) //从0开始循环母串,到momlen-sonlen停止 { int flag = 1; for (int j = 0; j < sonlen; j++) { if (momstr[i + j] != sonstr[j]) { flag = 0; break; //如果出现不相等就 退出循环,继续从下面一个寻找 } } if (flag) { return (&momstr); } } return NULL; } //指针法 char * mystrstraddr(char * const momstr, const char * const sonstr) { char * mstr = momstr; //母串 while (*mstr) { char * sstr = sonstr; //子串 char * momnowstr = mstr; //记录现在母串的位置 int flag = 1; while (*sstr != 0) { if (*sstr != *momnowstr || *momnowstr == '0') { flag = 0; break; } momnowstr++; sstr++; } if (flag) { return mstr; } mstr++; //母串对比位置+1 } return NULL; } void main() { char * str = "fengcong is too fucking handsome"; //printf("%p", strstr(str, "fengcong")); //printf("%p", mystrstrindex(str, "engcong")); printf("%p", mystrstraddr(str, "some")); system("pause"); }
5.itoa:整数转字符串
#define _CRT_SECURE_NO_WARNINGS #include<stdlib.h> #include<stdio.h> #include<string.h> char * myitoa(int value, char * str) { char * pstr = str; //str本身不能改变,一会要返回str if (value < 0) { *pstr = '-'; pstr++; value *= -1; //转变为正数处理 } int wei = 1; //数至少一位 int ivalue = value; //用于测试长度 while ((ivalue /= 10) != 0) { wei++; } pstr += wei-1; while (value % 10 != 0) { *pstr-- = (value % 10)+'0'; value /= 10; } return str; } void main() { int num = -45644; char str[20] = { 0 }; printf("%s", myitoa(num, str)); system("pause"); }
6.atoi:字符串转整数(遇到非数字字符结束)
#include<stdlib.h> #include<stdio.h> #include<string.h> int myatoi(const char * str) { if (str == NULL) { return 0; } int num = 0; //需要返回的值 int flag = 1; //记录正负号 if (*str == '-') { flag = -1; str++; } else if (*str == '+') { str++; } while (*str >= '0' && *str <= '9') { num= (num * 10 + (*str - '0')); str++; } return num*flag; } void main() { char str[20] = "-57124"; int num = 0; printf("%d\n",myatoi(str)); system("pause"); }
7.memcpy:拷贝某段内存
#include<stdio.h> #include<stdlib.h> #include<memory.h> //下标法 void * mymemcpybyindex(void * dest, const void * sor, size_t len) { if (dest == NULL || sor == NULL) { return NULL; } for (int i = 0; i < len; i++) { ((char*)dest) = ((char*)sor); } return dest; } //指针法 void * mymemcpybyaddr(void * dest, const void * sor, size_t len) { if (dest == NULL || sor == NULL) { return NULL; } char * pdest = dest; char * psor = sor; char * plast = (char * )sor + len; while (psor < plast) { *pdest++ = *psor++; } return dest; } void main() { char str[50] = "fengcong is fucking too handsome"; char * pstr = (char[50]) { 0 }; //在栈上开辟一段内存 //printf("%s\n", memcpy(pstr, str, 32)); printf("%s\n", mymemcpybyaddr(pstr, str, 31)); system("pause"); }
8.memset:对指定内存每个字节赋某个值
#include<stdio.h> #include<stdlib.h> #include<memory.h> //下标法 void * mymemsetbyindex(void * dest, int val, size_t len) { if (dest == NULL) { return NULL; } if (len == 0) { return dest; } char * p = dest; for (int i = 0; i < len; i++) { p = val; } return dest; } //指针法 void * mymemsetbyaddr(void * dest, int val, size_t len) { if (dest == NULL) { return NULL; } if (len == 0) { return dest; } char * p = dest; char * plast = p + len; while (p < plast) { *p++ = val; } return dest; } void main() { char str[50] = "fengcong is fucking too handsome"; //printf("%s\n", memset(str, 65, 8)); printf("%s\n", mymemsetbyaddr(str, 65, 8)); system("pause"); }
9.memmove:和memcpy类似,但是memmove采用了中间空间,memcpy是直接拷贝
两者区别之处在于当拷贝地址重复的时候,结果不一样(比较代码可知)
#include<stdlib.h> #include<stdio.h> #include<string.h> char * myftoa(double db, char * str) { char * pstr = str; //先判断 符号位 if (db < 0) { *pstr = '-'; db *= -1; //转为正数处理 pstr++; } //整数部分 int zhengshu = (int)db; int izhengshu = zhengshu; //牺牲于记录整数长度 int wei = 1; //整数部分至少一位 while ((izhengshu /= 10) != 0) { wei++; } pstr += wei - 1; for (int i = 0; i < wei; i++) { *pstr-- = zhengshu % 10 + '0'; zhengshu /= 10; } pstr += (wei+1); *pstr = '.'; pstr++; //小数部分 double xiaoshu = db - (int)db; for (int i = 0; i < 6; i++) { *pstr++ = (int)(xiaoshu * 10) + '0'; xiaoshu = xiaoshu * 10 - (int)(xiaoshu * 10); } return str; } void main() { double db = -2.11; char str[20] = { 0 }; printf("%s\n", myftoa(db,str)); system("pause"); }
10.memchr:某段内存中寻找某个值
#include<stdio.h> #include<stdlib.h> #include<memory.h> void * mymemchar(void * buf, int val, size_t size) { if (buf == NULL) { return NULL; } char * p = buf; char plast = p + size; while (p < plast) { if (*p == val) { return p; } p++; } return NULL; } void main() { char str[50] = "fengcong is fucking too handsome"; printf("%s\n", mymemchar(str, 'g', 8)); system("pause"); }
11.memccpy:内存拷贝,直到一个值结束
#include<stdio.h> #include<stdlib.h> #include<memory.h> //下标法 void * mymemccpybyindex(void * dest, const void * sor,int val, size_t len) { if (dest == NULL || sor == NULL) { return NULL; } for (int i = 0; i < len; i++) { if( (((char*)dest) = ((char*)sor)) == val) return dest; } return dest; } //指针法 void * mymemccpybyaddr(void * dest, const void * sor,int val, size_t len) { if (dest == NULL || sor == NULL) { return NULL; } char * pdest = dest; char * psor = sor; char * plast = (char *)sor + len; while (psor < plast) { if ((*pdest++ = *psor++) == val) return dest; } return dest; } void main() { char str[50] = "fengcong is fucking too handsome"; char * pstr = (char[50]) { 0 }; //在栈上开辟一段内存 //printf("%s\n", memccpy(pstr,str,'s',32)); printf("%s\n", mymemccpybyaddr(pstr, str, 'f', 32)); system("pause"); }
12.memicmp:比较某段内存大小(一个字节一个字节比较,像strcmp)
注意:切不可用来比较整数,除非一字节整数,因为整数存储方式是高位高字节
#include<stdio.h> #include<stdlib.h> #include<memory.h> int mymemicmpbyaddr(const void * buf1, const void * buf2, size_t size) { char * p1 = buf1; char * p2 = buf2; int i = 0; while(*p1 == *p2 && i < size) { p1++; p2++; i++; } if (*p1 > *p2) { return 1; } else if (*p1 < *p2) return -1; else return 0; } void main() { char str[50] = "fengcong is fucking too handsome"; char str1[50] = "fengfeng is fucking too handsome"; printf("%d\n", mymemicmpbyaddr(str, str1, 32)); system("pause"); }