1. 字符串的拷贝strcpy的实现
char *myStrcpy(char *dst,char *src)
{
char *ret = dst;
if(dst == NULL || src == NULL)
{
return NULL;
}
while((*dst++ = *src++)!= '\0')
;
*dst = '\0';
return ret;
}
2.返回字符串长度strlen实现
unsigned int myStrlen(const char *src)
{
// 安全性检查
if(src == NULL)
{
return 0;
}
const char *end = src;
// 返回的是'\0'之前的长度,不把'\0'算在内
while (*end++ != '\0')
;
return (unsigned int)(end - src);
}
3.字符串连接strcat实现
注意调用者必须保证dst有足够的空间否则造成内存越界
char *myStrcat(char *dst,const char *src)
{
if(dst == NULL || src == NULL)
{
return NULL;
}
char *ret = dst;
// 将指针指向字符串结尾处
while(*dst != '\0')
dst++;
// 执行和strcpy一样的操作
while ((*dst++ = *src++) != '\0')
;
return ret;
}
4.字符串比较函数strcmp实现
int myStrcmp(char *strA,char *strB)
{
int val = 0;
if(strA == NULL || strB == NULL)
{
return val;
}
// 将指针指到不相等处
while ((*strA != '\0') && (*strB != '\0') && (*strA == *strB))
{
strA++;
strB++;
}
// 注 如果不是返回 -1 0 1则此处直接使用 return *strA - *strB 即可
// 不相等要判断是大于还是小于
if(*strA != *strB)
{
val = *strA > *strB ? 1 : -1;
}
else
{
val = 0;
}
return val;
}
5. 将一个字符串逆序
讲一个字符串逆序有多重方式实现,下面的三种方式均是在原字符串上操作。
方式一.使用数组的方式操作
char *reversestr(char *str)
{
char *temp = str;
int indexLeft = 0;
int indexRight = 0;
if (str == NULL)
{
return NULL;
}
while(*temp != '\0')
{
indexRight++;
temp++;
}
//指向最后一个字符'\0'的前一个
indexRight = indexRight - 1;
while(indexRight > indexLeft)
{
char temp = str[indexLeft];
str[indexLeft++] = str[indexRight];
str[indexRight--] = temp;
}
return str;
}
方式二 .使用指针的方式操作
char *reverseStr(char *str)
{
char *left = str;
char *right = str;
if(str == NULL)
{
return NULL;
}
while (*right != '\0')
{
right++;
}
right--;
while (right > left)
{
char temp = *right;
*right++ = *left;
*left++ = temp;
}
return str;
}
方式三.不使用第三的变量
char *reversestr1(char *str)
{
char *left = str;
char *right = str;
if (str == NULL)
{
return NULL;
}
while(*right != '\0')
{
right++;
}
right--;
/*使用异或运算的特点 a = a^b^b b = a^b^a */
while (right > left)
{
*left = *left ^ *right;
*right = *left ^ *right;
*left = *left ^ *right;
left++;
right--;
}
return str;
}
6.在字符串中找出第一个只出现一次的字符串,如输入"abaccdeff",输出'b'
char firstNotRepeatingChar(char *str)
{
/* hash表存储 每个可能出现的字符作为索引值 数组内容即为出现的次数 */
char ret = '\0';
// 1.建立hashtable
const int size = 256;
// 全部初始化为0
int hashtable[size] = {0};
char *hashKey = str;
// 2.记录出现次数
while(*hashKey != '\0')
{
hashtable[*hashKey]++;
hashKey++;
}
// 3.查找返回
hashKey = str;
while(*hashKey != '\0')
{
if (hashtable[*hashKey] == 1)
{
ret = *hashKey;
return ret;
}
hashKey++;
}
return ret;
}
7. 整数装换为字符串atoi的实现
char *intToArray(int number, char *str)
{
if(str == NULL)
{
return NULL;
}
char *ret = str;
char *left = str;
char temp = '\0';
// 负数的处理
if(number < 0)
{
number = -number;
*ret++ = '-';
left++;
}
// 辗转对10求余法 分离各个位的数字
while (number > 0)
{
*ret++ = number%10 + '0'; // 将数字转化为ascall码
number = number/10;
}
*ret = '\0';
ret--;
/* 逆序 */
while (ret > left)
{
temp = *left;
*left++ = *ret;
*ret-- = temp;
}
return str;
}
8.字符串转为整数 arrayToInt
int arrayToInt(char *str)
{
// 需考虑字符串是负数 且是否包含字母
// 包含字母的处理 -123asd455 则为-123
// asd122作为0处理
/* 思路: 逐一遍历字符串 为空 或者 为字符就结束遍历 取出的字符逐一*10*/
long long val = 0;
int flag = 0;
char *src = str;
bool minus = false;
/* 安全性 */
if(str == NULL)
{
return 0;
}
// 处理正负符号的情况 无论正负都占一个位使指针加一
if(*src == '-')
{
src++;
minus = true;
}
else if (*src == '+')
{
src++;
}
while ((*src != '\0') && ((*src - '0' >= 0) && (*src - '0' <= 9)))
{
//逐位乘以10
flag = minus ? -1:1;
val = val * 10 + flag*(*src - '0');
/* 处理溢出问题:int最大值0x7FFFFFFF 最小值80000000 */
if(((minus) && (val > 0x7FFFFFFF)) ||
((!minus) && (val < (signed int)0x80000000)))
{
val = 0;
break;
}
src++;
}
printf("val= %d",(int)val*flag);
return (int)val;
}
9.查找字符串中最长子串
void findMaxLengthSubstr1(char *src)
{
char *start = src;
char *end = src;
unsigned int maxLength = 0;
unsigned int tempLength = 0;
// 此处子串长度不能超过100
char maxStr[100] = "0";
if (src == NULL)
{
return ;
}
while (*end != '\0')
{
while(*end != ' ')
{
// 到了字符串结尾处则也算是一个子串的结束必须跳出循环
if (*end == '\0')
{
break;
}
tempLength++;
end++;
}
// 判断空格之前单词长度是否大于记录的最大长度
if(maxLength < tempLength)
{
maxLength = tempLength;
// 只能存储长度小于100的 否则直接退出,
// 原则可以不支持,但必须保证程序没有异常不会挂机
if (maxLength < 100)
{
strncpy(maxStr,start,maxLength);
}
else
{
printf("The substr too length");
return;
}
}
// 无论长度是否大于maxLength只要到了间隔符都要指向空格符的下一个位置重新统计
end++;
start = end;
// 临时长度记录值清空,记录下一个子 串的长度
tempLength = 0;
}
printf("maxstr %s\n",maxStr);
return ;
}
10.替换空格:请实现一个函数,把字符串中的每个空格替换成“%20”例如输入“we are best ”,则输出we%20are%20 best
此题的实际意义是在网络编程中,如果URL中含有特殊的字符如空格、‘#’等可能导致服务器无法获取正常的参数,我们需要将特殊字符转换成服务器可以识别的字符。准换的规则是“%”加上ASCLL的两位十六制表示,如空格的ASCLL值是32则十六进制为0x20
void replaceBlank(char *src,int length)
{
int oriLength = 0;
int countBlank = 0;
int i = 0;
if (src == NULL && length <= 0)
{
return;
}
// 统计总长度和空格数
while (src[i] != '\0')
{
oriLength++;
if(src[i] == ' ')
{
countBlank++;
}
i++;
}
int newLength = oriLength + 2*countBlank;
// 新长度是否超限制
if (newLength > length)
{
return;
}
// 拷贝
int indexOri = oriLength;
int indexNew = newLength;
while (indexOri >= 0 && indexNew > indexOri)
{
if (src[indexOri] == ' ')
{
src[indexNew--] = '0';
src[indexNew--] = '2';
src[indexNew--] = '%';
}
else
{
src[indexNew--] = src[indexOri];
}
indexOri--;
}
printf("newstr= %s\n",src);
}