【C语言】字符串函数「超详细」_c语言字符串函数,Golang常用面试

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Golang全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip1024b (备注go)
img

正文

}

这样的运行结果就会是随机值,因为我们不知道反斜杠’\0’在哪里。

🎄创建自定义函数实现strlen()的功能🎄

示例代码如下:👇

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>//assert的头文件
int My_strlen(const char *arr)
{
unsigned int Count = 0;//统计字符不可能是为负数的!
assert(arr!=NULL);//这里加入到断言就能确保我们输入字符串的时候不会是空指针
while (*arr != ‘\0’)
{
Count++;
*arr++;
}
return Count;//返回计算机长度
}
int main(void)
{
char enter[20] = { 0 };
printf(“请输入字符串->:”);
scanf(“%s”, &enter);
int ret = My_strlen(enter);
printf(“The total number of input strings:%d\n”,ret);
return 0;
}

运行结果如下 👇

请输入字符串:C语言天下第一

The total number of input strings:7


🎄strcpy() - 复制字符串🎄

strcpy() 函数的声明方式如下****👇

char *strcpy(char *dest, const char *src)

把 src 所指向的字符串复制到 dest。

需要注意的是如果目标数组 dest 不够大,而源字符串的长度又太长,可能会造成缓冲溢出的情况。所以,dest 一定要足够大,这样才能被 src 给存放的下去。

dest****→ 指向用于存储复制内容的目标数组。

src****→ 要复制的字符串。

该函数返回一个指向最终的目标字符串 dest 的指针。

**strcpy()**在原来字符要保证拥有 src 存在字符的空间大小也就是下标。

注意:这里的返回值的指针类型可以是void *也可以是char *的类型。

🎄strcpy()函数代码示例🎄

使用**strcpy()**函数代码示例如下 👇

#include <stdio.h>
#include <string.h>

int main ()
{
char str1[]=“C语言”;
char str2[40];
char str3[40];
strcpy (str2,str1);
strcpy (str3,“C++语言”);
printf (“str1: %s\nstr2: %s\nstr3: %s\n”,str1,str2,str3);
return 0;
}

运行结果如下 👇

str1: C语言
str2: C语言
str3: C++语言

当然我们还要注意:**char str[ ] = {‘a’,‘b’,‘c’};**如果你是想这样子进行存放的话依旧还是不行的原因很简单’\0’,示例代码如下:

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>

int main()
{
char str1[] = { ‘a’, ‘b’, ‘c’ };
char str2[40];
strcpy(str2, str1);
printf(“%s”, str2);
return 0;
}

运行结果如下 👇

就会是这个样子具有随机值后面,因为我们不清楚’\0’到底在哪里。

当然如果是这样**char str1[] = { ‘a’, ‘b’, ‘c’,‘\0’};**就不会因为我们在最后一个元素添加了’\0’。

🎄创建自定义函数实现strcpy()的功能🎄

示例代码如下:👇

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
#include <assert.h>
void My_strcpy(char *dest, const char *src)
{
assert(dest != NULL);
assert(src != NULL);
while (*src != ‘\0’)
{
*dest = *src;//进行赋值
*src++;
*dest++;//指向下一个字符
}
}
int main(void)
{
char *p = “C语言”;
char str[20] = { 0 };
My_strcpy(str, p);
printf(“str = %s\n”,str);
return 0;
}

运行结果如下 👇

str = C语言


🎄strcat() - 连接字符串🎄

strcat() 函数的声明方式如下****👇

char *strcat(char *dest, const char *src)

将源字符串的副本追加到目标字符串。

dest → 指向目标数组,该数组包含了一个 C 字符串,且足够容纳追加后的字符串。

src → 指向要追加的字符串,该字符串不会覆盖目标字符串。

该函数返回一个指向最终的目标字符串 dest 的指针。

把 src 所指向的字符串追加到 dest 所指向的字符串的结尾。

不能自己给自己追加程序,像这样:

char arr[20] = “Cyuyan”
strcat(arr,arr);
printf(“%s\n”,arr);

这样子是不行的,本来我的这个数组存放的是:Cyuyan\0,因为这块空间足够长后面还是有内容的。那么如果我们要进行追加的话就会是这个样子:CyuyanCyuyan,本质上我们的斜杠0会在CyuyanCyuyan这个字符串n的后面。但是斜杠0被覆盖了,那么被谁覆盖的呢,就是被自己所追加的 arr 所覆盖了。这样就会构成循环,因为我们永远都找不到反斜杠0-O-

🎄strcat()函数代码示例🎄

使用strcat() 函数代码示例如下 👇

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
int main(void)
{
char arr1[20] = “hello C”;
char arr2[20] = “yuyan”;
strcat(arr1, arr2);
printf(“arr1 = %s\n”, arr1);
return 0;
}

运行结果如下 👇

arr1 = hello Cyuyan

让我们来看看它的调试结果的步骤🧐

🎄创建自定义函数实现strcat()的功能🎄

思路很简单其实 👇

Ⅰ→dest 找到目标字符串’\0’

Ⅱ→再把源数据追加到字符串’\0’的后面,注意:是包含’\0’的

示例代码如下:👇

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
char *My_strcat(char *dest, const char *src)
{
assert(dest && src != NULL);//断言
char *ret = dest;
while (*dest != ‘\0’)//‘\0’的ASCLL码值就是0
{
dest++;
}
//dest指向的是’\0’
while (*dest++ = *src++)
{
;
}
/*相当于
while (*src != ‘\0’)
{
*dest++ = src++;
}
/
return ret;
}
int main(void)
{
char arr1[20] = “hello C”;
char arr2[20] = “yuyan”;
printf(“%s\n”, My_strcat(arr1, arr2));
return 0;
}

运行结果如下 👇

hello Cyuyan

🍊⒈注→在上述的代码细节还是非常多的非常值得调试以下观察它的运行步骤。如

🍎⒉注→’\0’实际上也是对应着C语言的空字符NULL十进制为0的值。


🎄strcmp() - 比较字符串🎄

strcmp()函数的声明方式如下👇

int strcmp(const char *str1, const char *str2)

将 C语言 字符串 str1 与 C语言 字符串 str2 进行比较。

此函数开始比较每个字符串的第一个字符。 如果它们彼此相等,则继续以下对,直到字符不同或到达终止空字符。此函数执行字符的二进制比较。

str1 → 要进行比较的第一个字符串。

str2→ 要进行比较的第二个字符串。

比较每一位字符比较的大小是ASCll码的值。

该函数返回值如下:该函数具有返回值 int

如果返回值小于 0,则表示 str1 小于 str2。

如果返回值大于 0,则表示 str1 大于 str2。

如果返回值等于 0,则表示 str1 等于 str2。

🎄strcmp()函数代码示例🎄

使用strcmp() 函数代码示例如下 👇

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
int main()
{
char str1[20] = { 0 };
char str2[20] = { 0 };
puts(“请输入第一个字符串:”);
scanf(“%s”, &str1);
puts(“请输入第二个字符串:”);
scanf(“%s”, &str2);
puts(“返回的值:”);
printf(“%d”,strcmp(str1, str2));
return 0;
}

🎄第一次的运行结果🎄

请输入第一个字符串:abc
请输入第二个字符串:abc
返回的值:0

🎄第二次的运行结果🎄

请输入第一个字符串:abcd
请输入第二个字符串:abc
返回的值:1

🎄第三次的运行结果🎄

请输入第一个字符串:abc
请输入第二个字符串:abcd
返回的值:-1

🎄创建自定义函数实现strcmp()🎄

思路很简单其实 👇

相等为0、大于返回1、小于返回-1,重要的点注释其实都是写了的。

示例代码如下:👇

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
int my_strcmp(const char *str1, const char *str2)
{
assert(str1 && str2 != NULL);
while (*str1 == str2)
{
//判断相等情况,有一个相等就代表
str2也是一样的
if (*str1 == ‘\0’)
{
return 0;
}
*str1++;
*str2++;//自增比较
}
if (*str1 > *str2)
return 1;//大于
else
return -1;//小于
//其实还有一种更简单的方法,大于小于。
//return *str1 - *str2;
//这个是指针减指针的概念,前面介绍有说过!
}
int main()
{
char str1[20] = { 0 };
char str2[20] = { 0 };
puts(“请输入第一个字符串:”);
scanf(“%s”, &str1);
puts(“请输入第二个字符串:”);
scanf(“%s”, &str2);
int ret = my_strcmp(str1, str2);
printf(“返回的值:%d\n”,ret);
return 0;
}

🎄第一次的运行结果🎄

请输入第一个字符串:abc
请输入第二个字符串:abc
返回的值:0

🎄第二次的运行结果🎄

请输入第一个字符串:abcd
请输入第二个字符串:abc
返回的值:1

🎄第三次的运行结果🎄

请输入第一个字符串:abc
请输入第二个字符串:abcd
返回的值:-1

以上四个字符串函数是我们学C语言必须要掌握的,包括模拟字符串函数的实现也是有必要去实现的,这样的好处可以锻炼我们对函数库的了解,增强自己写代码的能力,建议反复观看,牢记掌握这四个字符串函数~


🔧 限制 🔧

上述 strcpy、strcat、strcmp、长度是不受限制的字符串函数

而下面所说的是长度受限制的字符串函数了>>>

起始记住下面这个只需要在上面的基础上加上个str后面+n即可(^∀^●)ノシ

下面所介绍的3种函数相对比上的使用要更加安全,但并不是绝对安全。


🎋strncpy() - 复制字符串(受长度限制)🎋

这个函数实际上和**strcpy()的功能是一模一样的,唯一不同的是在于strncpy()**多了一个参数,那个参数就是受长度所限制的。

strncpy()函数的声明方式如下****👇

char *strncpy(char *dest, const char *src, size_t n)

把 src 所指向的字符串复制到 dest,最多复制 n 个字符。

当 src 的长度小于 n 时,dest 的剩余部分将用空字节填充。

dest → 指向用于存储复制内容的目标数组。

src → 要复制的字符串。

n → 要从源中复制的字符数。

Size_t→是一个无符号整型类型。

该函数最终返回所复制的字符串。

🎋strncpy()函数代码示例🎋

使用**strncpy()**函数代码示例如下 👇

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
int main(void)
{
char str1[20] = “helloC”;
char str2[] = “HELLO”;
printf(“字节=%d\n”, sizeof(str2));
printf(“str = %s\n”,strncpy(str1, str2, sizeof(str2)));
return 0;
}

运行结果如下 👇

字节 = 6

str = HELLO

sizeof(str2) 相当于为 6个字节,因为 char 为一个字节 里面元素有6个包括’\0’

✅来一起看看调试结果说不定会更好点✅

我们再来看下一个例子👇

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
int main(void)
{
char str1[20] = “helloC”;
char str2[] = “HELLO”;
printf(“字节=%d\n”, sizeof(char));
printf(“str = %s\n”, strncpy(str1, str2, sizeof(char)));
return 0;
}

运行结果如下 👇

字节 = 1

str = HELLO

sizeof(char) 结果为一个字节,因为 char 类型大小为一个字节!

✅来一起看看调试结果说不定会更好点✅

🎋strncpy()源程序实现🎋

示例代码如下:👇

char * __cdecl strncpy (
char * dest,
const char * source,
size_t count
)
{
char *start = dest;

while (count && (*dest++ = source++)) / copy string */
count–;

if (count) /* pad out with zeroes */
while (–count)
*dest++ = ‘\0’;

return(start);
}


🎋strncat() - 连接字符串(受长度限制)🎋

strncat()函数的声明方式如下****👇

char *strncat(char *dest, const char *src, size_t n)

把 src 所指向的字符串追加到 dest 所指向的字符串的结尾,直到 n 的长度为止。

dest→指向目标数组,该数组包含了一个 C语言 字符串,且足够容纳追加后的字符串,包括额外的空字符。

src→要追加的字符串。

n→追加的最大字符串。

Size_t→是一个无符号(unisgned int)整型类型。

该函数返回一个指向最终的目标字符串 dest 的指针。

注意:这里的返回值的指针类型可以是void也可以是char *🧨

🎋strncat()函数代码示例🎋

使用**strncpy()**函数代码示例如下 👇

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
int main(void)
{
char str1[20];
char str2[20];
strcpy(str1, “Cyuyan”);
strcpy(str2, “yyds”);
printf(strncat(str1, str2, 5));//追加字符串!
return 0;
}

运行结果如下 👇

Cyuyanyyds

✅来一起看看调试结果说不定会更好点✅

我们把 Size_t 参数改为④来看看

printf(strncat(str1, str2, 4));

运行结果依旧和上述结果是一样的。

🎋strncat()源程序实现🎋

示例代码如下:👇

char * __cdecl strncat (
char * front,
const char * back,
size_t count
)
{
char *start = front;

while (*front++)
;
front–;

while (count–)
if (!(*front++ = *back++))
return(start);

*front = ‘\0’;
return(start);
}

🎋strncmp() - 比较字符串(受长度限制)🎋

strncmp()函数的声明方式如下****👇

int strncmp(const char *str1, const char *str2, size_t n)

str1 → 要进行比较的第一个字符串。

str2 → 要进行比较的第二个字符串。

n → 要比较的最大字符数。

这个函数开始比较每个字符串的第一个字符。如果它们相等,则继续执行下面的对,直到字符不同,直到达到一个结束的空字符,或直到两个字符串中的num字符匹配,以先发生的为准。

如果返回值 < 0,则表示 str1 小于 str2。

如果返回值 > 0,则表示 str2 小于 str1。

如果返回值 = 0,则表示 str1 等于 str2。

🎋strncmp()函数代码示例🎋

使用**strncpy()**函数代码示例如下 👇

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
int main(void)
{
char str1[20];
char str2[20];
strcpy(str1, “Cyuyan”);
strcpy(str2, “Cyuyanyyds”);
printf(“%d”, strncmp(str1, str2, 6));

return 0;
}

运行结果如下 👇

0 → 代表****str1 等于 str2

如果这里没有追加字符串的话结果就会是-1,因为str1<str2。正因为我们追加了字符为6,它才可以是str1 = str2。

🎋strncmp()源程序实现🎋

示例代码如下:👇

int __cdecl strncmp
(
const char *first,
const char *last,
size_t count
)
{
size_t x = 0;

if (!count)
{
return 0;
}

/*

  • This explicit guard needed to deal correctly with boundary
  • cases: strings shorter than 4 bytes and strings longer than
  • UINT_MAX-4 bytes .
    /
    if( count >= 4 )
    {
    /
    unroll by four */
    for (; x < count-4; x+=4)
    {
    first+=4;
    last +=4;

if (*(first-4) == 0 || *(first-4) != (last-4))
{
return(
(unsigned char *)(first-4) - *(unsigned char *)(last-4));
}

if (*(first-3) == 0 || *(first-3) != (last-3))
{
return(
(unsigned char *)(first-3) - *(unsigned char *)(last-3));
}

if (*(first-2) == 0 || *(first-2) != (last-2))
{
return(
(unsigned char *)(first-2) - *(unsigned char *)(last-2));
}

if (*(first-1) == 0 || *(first-1) != (last-1))
{
return(
(unsigned char *)(first-1) - *(unsigned char *)(last-1));
}
}
}

/* residual loop */
for (; x < count; x++)
{
if (*first == 0 || *first != last)
{
return(
(unsigned char *)first - *(unsigned char *)last);
}
first+=1;
last+=1;
}

return 0;
}


🎍strstr() - 在一个字符串中查找另外一个字符串🎍

strstr()函数的声明方式如下****👇

char *strstr(const char *haystack, const char *needle)

在字符串 haystack 中查找第一次出现字符串 needle 的位置,不包含终止符 ‘\0’。

haystack→ 要被检索的 C 字符串。

needle→ 在 haystack 字符串内要搜索的小字符串。

该函数返回在 haystack 中第一次出现 needle 字符串的位置,如果未找到则返回 null。

注意:这里的返回值的指针类型可以是void也可以是char *🧨

🎍strstr()函数代码示例🎍

题目:在arr1中查找是否包含arr2中的数组。要求使用 strstr() 库函数。

使用**strncpy()**函数代码示例如下 👇

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
int main(void)
{
char arr1[20] = “abcdef”;
char arr2[20] = “bcd”;
char ret = strstr(arr1, arr2);
if (ret == NULL)
{
printf(“没找到!\n”);
}
else
{
printf(“找到了→%s\n”, ret);
}
return 0;
}

运行结果如下 👇

找到了→bcdef

那没找到的情况下,我们把 arr2 数组修改下。其它值不变🎉

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<assert.h>
int main(void)
{
char arr1[20] = “abcdef”;
char arr2[20] = “bf”;
char *ret = strstr(arr1, arr2);
if (ret == NULL)
{
printf(“没找到%s!\n”,ret);
}
else
{
printf(“找到了→%s\n”, ret);
}
return 0;
}

运行结果如下 👇

找不到(null)!

对比之下,你发现了区别了没👀

🎍创建自定义函数实现strstr()🎍

分析思路🧐

其实很容易,我们只需要拿首字符地址进行比较相等的话返回,不相等的时候进行自增++(注意:这里自增++只需要str1进行++而str2依旧拿首元素地址跟它进行比较),再进行比较直到’\0’,没有就返回空指针NULL。如果str1有元素和str2首元素地址匹配上了的话那么就继续往后走~但是,这个仅仅是假设 abcd 和 bcd 所适用的场景。如果是 bbbc 和 bbc,这种怎么办?是不是发现用这种思路不行,下面就用代码来讲解下怎么实现。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Go)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
int main(void)
{
char arr1[20] = “abcdef”;
char arr2[20] = “bcd”;
char ret = strstr(arr1, arr2);
if (ret == NULL)
{
printf(“没找到!\n”);
}
else
{
printf(“找到了→%s\n”, ret);
}
return 0;
}

运行结果如下 👇

找到了→bcdef

那没找到的情况下,我们把 arr2 数组修改下。其它值不变🎉

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<assert.h>
int main(void)
{
char arr1[20] = “abcdef”;
char arr2[20] = “bf”;
char *ret = strstr(arr1, arr2);
if (ret == NULL)
{
printf(“没找到%s!\n”,ret);
}
else
{
printf(“找到了→%s\n”, ret);
}
return 0;
}

运行结果如下 👇

找不到(null)!

对比之下,你发现了区别了没👀

🎍创建自定义函数实现strstr()🎍

分析思路🧐

其实很容易,我们只需要拿首字符地址进行比较相等的话返回,不相等的时候进行自增++(注意:这里自增++只需要str1进行++而str2依旧拿首元素地址跟它进行比较),再进行比较直到’\0’,没有就返回空指针NULL。如果str1有元素和str2首元素地址匹配上了的话那么就继续往后走~但是,这个仅仅是假设 abcd 和 bcd 所适用的场景。如果是 bbbc 和 bbc,这种怎么办?是不是发现用这种思路不行,下面就用代码来讲解下怎么实现。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Go)
[外链图片转存中…(img-84jzeDj9-1713434632462)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值