带你快速了解字符(串)函数(一)

简介: 带你快速了解字符(串)函数(一)

本文重点


函数作用 函数名
求字符串长度 strlen
长度不受限制的字符串函数 strcpy strcat strcmp
长度受限制的字符串函数 strncpy strncat strncmp
字符串查找 strstr strtok
错误信息报告 strerror
内存操作函数 memcpy memmove memset memcmp
字符操作


C语言中对字符和字符串的处理很是频繁,但是C语言本身是没有字符串类型的,字符串通常放在常量字符串中或者字符数组中。


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


1. strlen函数


功能: 获取字符串长度


size_t strlen ( const char * str );//返回字符串str的长度
//str--字符串

字符串的长度由终止空字符 '\0' 确定:字符串的长度与字符串开头和终止空字符之间的字符数一样长(不包括终止空字符本身)。


🍤 例如:


char str[100]="string ";

定义了一个大小为 100 个字符的字符数组,但初始化 str 时使用的字符串的长度仅为 7 个字符。因此,当 sizeof(str) 的计算结果为 100 时,strlen(str) 返回 7。

bd7ea215f1f39fd5bf8ad45986b6baf7_620fbdefcc2f4ceebacd975da3d5fd6a.png



通过 strlen函数 比较两个字符串大小


//有符号
#include<stdio.h>
#include<string.h>
int main()
{
  const char* str1 = "abcdef";
  const char* str2 = "bbb";
  if ((int)strlen(str2) -(int) strlen(str1) > 0)
  {
    printf("str2>str1\n");
  }
  else
  {
    printf("srt1>str2\n");
  }
  return 0;
}

🍤 打印结果:

c18d1566a0687db7c9790bd95af9f943_53a831ff9d874b0e807f84595e252b4c.png


//无符号的
#include<stdio.h>
#include<string.h>
int main()
{
  const char* str1 = "abcdef";
  const char* str2 = "bbb";
  if (strlen(str2) - strlen(str1) > 0)
  {
    printf("str2>str1\n");
  }
  else
  {
    printf("srt1>str2\n");
  }
  return 0;
}

🍤 打印结果:

d85bb9ce30d20c6c948372cc71c0fb64_d5238272233e4cbcaa6d46f58a48d92f.png

因为函数返回值是无符号的


注:

🍥 字符串str以 ‘\0’ 作为结束标志,strlen函数返回的是在字符串中 ‘\0’ 前面出现的字符个数(不包含 ‘\0’ )。


🍥 参数指向的字符串必须要以 ‘\0’ 结束。

如果没有 ‘\0’ 结尾,长度会一直计算下去,直到遇到 ‘\0’ 。


🍥 注意函数的返回值为size_t,是无符号的。


1.1 模拟实现

#include<stdio.h>
size_t my_strlen(const char* str)
{
  int count = 0;
  while (*str != '\0')//终止条件
  {
    count++;//累计 计算字符串长度
    str++;
  }
  return count;
}
int main()
{
  size_t sz = my_strlen("abc");//无符号类型
  printf("%u\n", sz);//打印无符号十进制整型
  return 0;
}


2. strcpy函数


功能: 复制字符串


char * strcpy ( char * destination, const char * source );
//destination(目的地)--指向要在其中复制内容的目标数组的指针
//source(源)--要复制的字符串

将源指向的字符串复制到目标指向的数组中,包括终止的 ‘\0’ 字符(并在该点停止)。


为避免溢出,目标指向的数组的大小应足够长,以包含与源相同的字符串(包括终止空字符),并且不应在内存中与源重叠。


🍤 实例1:

#include <stdio.h>
#include<string.h>
int main()
{
  char str1[] = "Sample string";
  char str2[40];
  char str3[40];
  strcpy(str2, str1);//将str1拷贝到str2
  strcpy(str3, "copy successful");
  printf("str1: %s\nstr2: %s\nstr3: %s\n", str1, str2, str3);
  return 0;
}

🍤 运行结果:


ecbb84cf4c99b7a923fd55279609fcb0_4dd920f3b19b45af896170eb9f2ab929.png


🍤 实例2:


#include <stdio.h>
#include<string.h>
int main()
{
  char arr1[] = "xxxxxxxxxx";
  char arr2[5] = { 'a', 'b', 'c', 'd', 'e' };
  strcpy(arr1, arr2);//将 arr2 里的东西拷贝到 arr1 中
  printf("%s\n", arr1);
  return 0;
}

🍤 运行结果:

f59407be361527b3d0dcd15329d8d922_cb6ce9074b0f4980a10d299ec10d0257.png


为什么结果不是 abcde 呢?

我们在调试时,打开监视窗口观察arr1的变化,虽然 abced 已拷贝给 arr1, 但没有发现结束标志,所以在创建 arr2 时,要在最后加上 ‘\0’

06b10b9cb8247a5b72151cb9a6f0391f_7adab455d46348948c7e462858c68546.png

bec767bbbd2e7d4793c63e0e84a38d20_d68d85f16ed04d03a33ba78213b3d47e.png

添加了结束标志的 arr2 :

1f83cb1a9c54488c8e0060b3590ddc04_0af7ca02f5d94a71a5e60c2282d2e933.png


注:

🍥 源字符串必须以 ‘\0’ 结束。


🍥 会将源字符串中的 ‘\0’ 拷贝到目标空间。


🍥 目标空间必须足够大,以确保能存放源字符串。


🍥 目标空间必须可变。


2.1 模拟实现

#include<stdio.h>
#include<assert.h>
char* my_strcpy(char* dest, const char* src)
{
  char* ret = dest;
  assert(dest != NULL);//若字符串为空,就停止运行,并提示
  assert(src != NULL);
  while (*src != '\0')
  {
    *dest = *src;//实现拷贝
    dest++;//后移一个字符
    src++;
  }
  *dest = *src;// '\0'
  return ret;
}
int main()
{
  char arr1[20] = "hello world";
  char arr2[] = "xxxxx";
  my_strcpy(arr1 + 6, arr2);//从arr1的第六个字符之后开始拷贝arr2
  printf("%s\n", arr1);
  return 0;
}

🍤 运行结果:


9c35a63c2ce6dd4d4488a5853622d226_3ae237eef3904e15b80b2cee73cde060.png


🍩补充:


assert(表达式)--表达式为真时, 程序继续运行, 如果表达式为假, 那程序就会停止运行, 并提示错误信息

相关文章
|
6月前
|
存储 算法 编译器
|
6月前
字符拼接的深入理解
字符拼接的深入理解
31 0
|
5月前
|
C#
C# 中的字符与字符串
C# 中的字符与字符串
带你快速了解字符(串)函数(二)
带你快速了解字符(串)函数(二)
带你快速了解字符(串)函数(三)
带你快速了解字符(串)函数(三)
实现一个函数,可以左右旋字符串中的k个字符
实现一个函数,可以左右旋字符串中的k个字符 ABCD左旋一个字符得到BCDA ABCD左旋两个字符的到CDAB ABCD右旋一个字符得到DABC ABCD右旋两个字符的到CDAB
|
存储 编译器
C中的字符串
C中的字符串
94 0