【C语言进阶】带你轻松玩转字符、字符串函数(上)

简介: 【C语言进阶】带你轻松玩转字符、字符串函数(上)

前言

我们在之前C语言初阶的时候,用到了strlen之类的字符串函数我们也知道字符串函数的头文件为<string.h>在这里我们继续向大家介绍其他字符串函数,以及模拟实现这些字符串函数

字符串函数有很多种,我们接下来介绍的是比较常用的几种函数。

一、字符串函数存在的意义

C语言中对字符和字符串的处理很是频繁,但是C语言本身是没有字符串类型的。

1.字符串通常放在常量字符串中或者字符数组中。

2.字符串常量 适用于那些对它不做修改的字符串函数

二、函数介绍

2.1 strlen

size_t strlen ( const char * str );          求得字符串长度

函数特性:

1.字符串已经 '\0' 作为结束标志,strlen函数返回的是在字符串中 '\0' 前面出现的字符个数(不包含 '\0' )

2.参数指向的字符串必须要以 '\0' 结束。

3.注意函数的返回值为size_t,是无符号的( 易错 )

代码实现:

模拟strlen函数:

#include<stdio.h>
#include<string.h>
#include<assert.h>
int my_strlen1(const char* src) {
  assert(src);//断言
  int count = 0;
  while (*src++) {
    count++;
  }
  return count;
}
//使用递归的方法
int my_strlen2(const char* src) {
  if (*src==0) {
    return 0;
  }
  else {
  /*  src++;*/
    return 1 + my_strlen2(++src);
  }
}
//使用指针-指针   (得到是之间的元素个数)
int my_strlen3(const char* src) {
  char* ret = src;
  while (*src) {
    src++;
  }
  return src - ret;
}
int main()
{
  char arr[] = "abcdef";
  int len = my_strlen3(arr);
  printf("%d\n", len);
  return 0;
}

2.2 strcpy

char* strcpy(char * destination, const char * source );  

拷贝函数,将source内容拷贝到destination上。

函数特性:

1.源字符串必须以 '\0' 结束。   (src有'\0')

2.会将源字符串中的 '\0' 拷贝到目标空间。        ('\0'会拷贝到dest上)
3.目标空间必须足够大,以确保能存放源字符串。        (dest要足够大,大于等于src)
4.目标空间必须可变                (strcpy函数修改的是dest,所以dest能被修改)

代码演示:

模拟strcpy函数:

#include<stdio.h>
#include<string.h>
#include<assert.h>
char *my_strcpy(char* dest, const char* src) {
  assert(dest && src);
  char* ret = dest;
  while (*dest++ = *src++) {
    ;
  }
  return ret;
}
int main()
{
  char arr1[10] = "123456789";
  char arr2[] = "abcdef";
  my_strcpy(arr1, arr2);
  printf("%s\n", arr1);
  return 0;
}

2.3 strcat

char * strcat ( char * destination, const char * source );

覆盖destination上的' \0 '上继续加上source的内容  ,追加字符串函数

函数特性:

1.源字符串必须以 '\0' 结束。    (这是因为strcat之后,dest的'\0'被src第一个元素覆盖)
2.目标空间必须有足够的大,能容纳下源字符串的内容。 (dest大于等于src+dest空间)
3.目标空间必须可修改。        (dest是会被改变的)

函数实现:

模拟strcat函数:

#include<stdio.h>
#include<string.h>
#include<assert.h>
char*my_strcat(char* dest, const char* src) {
  assert(dest && src);
  //断言
  //我们需要的是找到dest的'\0'位置,在这个后面开始赋值
  char* ret = dest;
  while (*++dest) {  //找'\0'的时候 先++ ,这样避免算进去'\0'
    ;
  }
  while (*dest++ = *src++) {
    ;
  }
  return ret;
}
int main()
{
  char arr1[20] = "hello ";
  char arr2[] = "world!";
  my_strcat(arr1, arr2);
  printf("%s\n", arr1);
  return 0;
}

这边还有一个问题,供大家思考,如果是字符串自己给自己追加,会发生什么?

所以我们得出结论,字符串不能自己追加自己,会死循环 !!!

2.4 strcmp

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

strcmp函数:是对字符串进行比较的函数。

第一个字符串大于第二个字符串,则返回大于0的数字
第一个字符串等于第二个字符串,则返回0
第一个字符串小于第二个字符串,则返回小于0的数字

代码演示:

模拟strcmp函数

#include<stdio.h>
#include<string.h>
#include<assert.h>
int my_strcmp(const char* dest, const char* src) {
  assert(dest && src);//断言
  while (*dest++ == *src++&&*dest!='\0'&&*src!='\0') {
    //要保证的是,出来之后的dest和src的地址,是起码有一方到'\0'的地址
    //所以  *dest!='\0'&&*src!='\0'  
    //这样就可以停止了,对这样的进行判断
    ;
  }
  if (*dest < *src) {
    return -1;
  }
  else if (*dest > *src) {
    return 1;
  }
  else  {
    return 0;
  }
}
int main()
{
  char arr1[]="abcdef";
  char arr2[] = "abc";
  char arr3[] = "abc";
  char arr4[] = "a";
  int num1=my_strcmp(arr1, arr2);
  printf("%d\n", num1);
  int num2 = my_strcmp(arr3, arr2);
  printf("%d\n", num2);
  int num3 = my_strcmp(arr4, arr2);
  printf("%d\n", num3);
  return 0;
}

2.5 strncpy

char * strncpy ( char * destination, const char * source, size_t num );

与strcpy函数相比,多个n,表示多个参数num,意味拷贝num个字节的数据

代码演示:

代码演示:

#include<stdio.h>
#include<string.h>
#include<assert.h>
char* my_strncpy(char* dest, const char* src,size_t num) {
  assert(dest && src);
  char* ret = dest;
  int count = 0;
  while (*dest++ = *src++) {
    count++;
    if (count == num) {
      break;
    }
  }
  return ret;
}
int main()
{
  char arr1[10] = "123456789";
  char arr2[] = "abcdef";
  my_strncpy(arr1, arr2,3);
  printf("%s\n", arr1);
  return 0;
}

对于这样的限制字节的字符串函数,模拟实现,只需要在相应的位置上加上num的限制即可

2.6 strncat

char * strncat ( char * destination, const char * source, size_t num );

代码演示:

模拟实现strncat:

#include<stdio.h>
#include<string.h>
#include<assert.h>
char* my_strncat(char* dest, const char* src,size_t num) {
  assert(dest && src);
  //断言
  //我们需要的是找到dest的'\0'位置,在这个后面开始赋值
  char* ret = dest;
  while (*++dest) {  //找'\0'的时候 先++ ,这样避免算进去'\0'
    ;
  }
  int count = 0;
  while (*dest++ = *src++) {
    count++;
    if (count == num) {
      break;
    }
  }
  return ret;
}
int main()
{
  char arr1[20] = "hello ";
  char arr2[] = "world!";
  my_strncat(arr1, arr2,3);
  printf("%s\n", arr1);
  return 0;
}

2.7 strcmp

int strncmp ( const char * str1, const char * str2, size_t num );

代码演示:

模拟strncmp:

#include<stdio.h>
#include<string.h>
#include<assert.h>
int my_strncmp(const char* dest, const char* src,size_t num) {
  assert(dest && src);//断言
  int count = 0;
  while (*dest == *src && *dest != '\0' && *src != '\0') {
    //要保证的是,出来之后的dest和src的地址,是起码有一方到'\0'的地址
    //所以  *dest!='\0'&&*src!='\0'  
    //这样就可以停止了,对这样的进行判断
    count++;
    if (count == num) {
      break;
    }
    dest++;
    src++;
  }
  if (*dest < *src) {
    return -1;
  }
  else if (*dest > *src) {
    return 1;
  }
  else {
    return 0;
  }
}
int main()
{
  char arr1[]="abcdef";
  char arr2[] = "abc";
  char arr3[] = "abc";
  char arr4[] = "a";
  int num1=my_strncmp(arr1, arr2,1);
  printf("%d\n", num1);
  int num2 = my_strncmp(arr3, arr2,1);
  printf("%d\n", num2);
  int num3 = my_strncmp(arr4, arr2,1);
  printf("%d\n", num3);
  return 0;
}


相关文章
|
23天前
|
存储 算法 C语言
【C语言】字符常量详解
字符常量是C语言中处理字符数据的重要工具。通过单引号括起一个字符,我们可以方便地使用字符常量进行字符判断、字符运算和字符串处理等操作。理解字符常量的表示方法、使用场景和ASCII码对应关系,对于编写高效的C语言程序至关重要。
96 11
|
23天前
|
存储 C语言 开发者
【C语言】格式化输出占位符及其标志字符详解(基于ISO/IEC 9899:2024)
在C语言中,格式化输出通过 `printf` 函数等格式化输出函数来实现。格式说明符(占位符)定义了数据的输出方式,标准ISO/IEC 9899:2024(C23)对这些格式说明符进行了详细规定。本文将详细讲解格式说明符的组成部分,包括标志字符、宽度、精度、长度修饰符和类型字符,并适当增加表格说明。
40 6
|
2月前
|
C语言
C语言字符(串)函数
C语言字符(串)函数
|
2月前
|
C语言 C++
【C语言】解决不同场景字符串问题:巧妙运用字符串函数
【C语言】解决不同场景字符串问题:巧妙运用字符串函数
|
2月前
|
存储 C语言
【c语言】字符串函数和内存函数
本文介绍了C语言中常用的字符串函数和内存函数,包括`strlen`、`strcpy`、`strcat`、`strcmp`、`strstr`、`strncpy`、`strncat`、`strncmp`、`strtok`、`memcpy`、`memmove`和`memset`等函数的使用方法及模拟实现。文章详细讲解了每个函数的功能、参数、返回值,并提供了具体的代码示例,帮助读者更好地理解和掌握这些函数的应用。
41 0
|
2月前
|
存储 安全 编译器
深入C语言库:字符与字符串函数模拟实现
深入C语言库:字符与字符串函数模拟实现
|
3月前
|
存储 C语言
【C语言基础考研向】10 字符数组初始化及传递和scanf 读取字符串
本文介绍了C语言中字符数组的初始化方法及其在函数间传递的注意事项。字符数组初始化有两种方式:逐个字符赋值或整体初始化字符串。实际工作中常用后者,如`char c[10]=&quot;hello&quot;`。示例代码展示了如何初始化及传递字符数组,并解释了为何未正确添加结束符`\0`会导致乱码。此外,还讨论了`scanf`函数读取字符串时忽略空格和回车的特点。
113 8
|
2月前
|
C语言
C语言常见字符函数和字符串函数精讲
C语言常见字符函数和字符串函数精讲
|
2月前
|
C语言
【C语言】模拟实现深入了解:字符串函数
【C语言】模拟实现深入了解:字符串函数
|
3月前
|
存储 人工智能 C语言
C语言程序设计核心详解 第六章 数组_一维数组_二维数组_字符数组详解
本章介绍了C语言中的数组概念及应用。数组是一种存储同一类型数据的线性结构,通过下标访问元素。一维数组定义需指定长度,如`int a[10]`,并遵循命名规则。数组元素初始化可使用 `{}`,多余初值补0,少则随机。二维数组扩展了维度,定义形式为`int a[3][4]`,按行优先顺序存储。字符数组用于存储字符串,初始化时需添加结束符`\0`。此外,介绍了字符串处理函数,如`strcat()`、`strcpy()`、`strcmp()` 和 `strlen()`,用于拼接、复制、比较和计算字符串长度。