1. atoi()实现
atio:将字符串中的字符转为数字
enum Status
{
VALID,
INVALID
}status = INVALID; // 创建枚举变量名status它的值为非法 默认非法省事
int my_atoi(const char* str)
{
int flag = 1;
// 空指针
assert(str);
// 空字符串
if (*str == '\0')
{
return 0;
}
// isspace判断是否是空格的函数
while (isspace(*str))
{
str++;
}
// 正负号
if (*str == '+')
{
flag = 1;
str++;
}
else if (*str == '-')
{
flag = -1;
str++;
}
long long n = 0;
while (*str!='\0')
{
if (isdigit(*str))
{
// 乘以flag,使得负数能加上
n = n * 10 + flag * (*str - '0');
// n加完再判断
if (n < INT_MIN || n > INT_MAX)
{
n = 0;
break;
}
}
else
{
break;
}
str++;
}
if (*str == '\0')
{
status = VALID;
}
return n;
}
int main()
{
// atoi把字符串转换成整型数的一个函数
char arr[20] = " -1234888";
int ret = my_atoi(arr);
if (status == VALID)
{
printf("正常转换%d\n", ret);
}
else
{
printf("非法转换:%d\n", ret);
}
return 0;
}
以下都是长度受限制的字符串函数的实现,带n表示需要明确拷贝、追加、比较的长度
2. strncpy:
strcpy():字符串拷贝函数
学会使用 while(*dest++=*src++)
- 下面是strcpy()的实现
void my_strcpy(char* dest, const char* src)
{
// 传入错误值报错
assert(dest && src);
// 即使最后是\0,也会先赋值,拷贝成功后整体变为0,也会使得while停
while (*dest++=*src++)
{;}
}
标准的my_strcpy()会返回目标空间起始地址,所以起始时候拿char* res = dest; 再 return res;
- strncpy(*dest, *src, int n)的实现:
分两种情况:1. n大于src时,2. n小于等于src时:
- src不够,则补’\0’;
- 小于或者等于就全复制,等于的话,dest会把src的’\0’也全复制上。但是小于的话,给src下一位变为‘\0’,不然会漏。
void my_strcnpy(char* dest, char* src, int n)
{
assert(dest && src);
// 这里没有src长度,只要src存在,就进来做
while(*src)
{
while (*dest++ = *src++)
{
// 外面做条件的时候,已经复制了一次。
n--;
// 已经复制了n个 要停止了
if (n == 0)
{
*dest++ = '\0'; // 防止n小于src长度,最后结尾无'\0';
break;
}
}
}
while (n>0)
{
*dest++ = '\0';
n--;
}
}
int main()
{
char s1[10] = "abba";
char s2[10] = "";
char s3[10] = "";
char s4[10] = "";
my_strcnpy(s2, s1, 4);
my_strcnpy(s3, s1, 2);
my_strcnpy(s4, s1, 8);
printf("%s\n", s1);
printf("%s\n", s2);
printf("%s\n", s3);
printf("%s\n", s4);
return 0;
}
s2、s3、s4:分别对应长度正好、长度短缺、长度大于情况,且运行均正常
3.strncat:长度受限的字符串追加函数
- strcat():字符串追加函数
- 把src字符串追加给dest。
- 寻找dest的’\0’,这是末位。把’\0’开始的值换为dest。
- 不必考虑给src末位再加’\0’,因为挨个复制dest,dest末位有’\0’。
- 与cmp不同在先循环找dest末位。
void my_strncat(char* dest, char* src)
{
assert(dest && src); // dest和src要同时存在
// 1. 先找目标的\0
while (*dest)
{
dest++;
}
while (*dest++ = *src++)
{
;
}
}
- strncat()的思路:受限的字符串追加函数
- 给字符串s1后追加s2的n个.。有两种情况,n大于s2,n小于等于s2。
- n>len(s2),则把s2都加上,如果s2没有了,剩余都补’\0’;
- 如果n<len(s2),则取n个s2值,给src
- n小于的s2长度的情况,追加n个,都别忘了最后给s1最后加’\0’;
char* my_strncat(char* dest, char* src, int sz)
{
assert(dest && src); // dest和src要同时存在
// 1. 先找目标的\0
char* res = dest;
while (*dest)
{
dest++;
}
// 现在dest是\n sz大于src的长度
while (*src)
{
if (sz > 0)
{
*dest++ = *src++;
sz--;
}
else {
return res;
}
}
// src不存在,但是要追加sz个,就给它补充0
if (sz == 0)
{
return res;
}
while (sz)
{
*dest++ = '\0';
sz--;
}
*dest++ = '\0';
return res;
}
int main()
{
// 测试 my_strncat
char src[6] = "bbbbb";
char dest[25] = "aaaa";
printf("长度为:%d\n", strlen(src));
my_strncat(dest, src, 5);
printf("111");
return 0;
}
运行测试:
-
追加长度n大于src长度时正常:
-
n小于src时正常:
3. 等于src正常:
4. strncmp:长度受限的字符串比较函数
- strcmp()的思路:
- 比较字符串大小需要一位位比较,且每位只有两种情况:当前等或不等。
- 相等比较复杂:如果等,则看是否其中之一为’\0’,为空则返回0,因为说明两个一直相等,然后往后挪动指针后也,现在都已处在了结尾或者也或许一开始比就是两个空字符串。如果当前不是’\0’,就往后挪动指针:s1++,s2++,继续比较后面。
- 如果当前位不等,没有进循环,直接返回*s1-*s2;负数说明前面小,反之前面大。
int my_strncmp(char* s1, char*s2)
{
assert(s1 && s2);
while (*s1 == *s2)
{
if (*s1 == '\0')
{
return 0;
}
s1++;
s2++;
}
return *s1 - *s2;
}
- strncmp思路:
- 在strcmp基础上多了一个n的限制,即在n个字符之内,判断出它俩谁大小。
- 只要在s1和s2相同部分做限定,因为如果在小于n的地方,两个字符串不同,就会出while循环。不必考虑。
- 只需要注意while相等时,已经比了n位,就退出并且说明n字符内,两个串相等。
- 运行结果: