【编织代码之纵横字符与绚丽字符串](上)

简介: 【编织代码之纵横字符与绚丽字符串]

本章重点:重点介绍处理字符和字符串的库函数的使用和注意事项


求字符串长度

  • strlen

长度不受限制的字符串函数

  • strcpy
  • strcat
  • strcmp

长度受限制的字符串函数介绍

  • strncpy
  • strncat
  • strncmp

字符串查找

  • strstr
  • strtok

错误信息报告

  • strerror

字符操作

内存操作函数

  • memcpy
  • memmove
  • memset
  • memcmp


1、函数介绍


1.1、strlen


size_t strlen ( const char * str );


  • 字符串已经 '\0' 作为结束标志,strlen函数返回的是在字符串中 '\0' 前面出现的字符个数(不包 含 '\0' )。
  • 参数指向的字符串必须要以 '\0' 结束。
  • 注意函数的返回值为size_t,是无符号的( 易错 )
  • 学会strlen函数的模拟实现


首先先来看一段代码:


#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;
}


运行结果:



      解释:在这段代码中,比较的是两个字符串的长度,而不是字符串本身的内容。因为 strlen()函数用于计算字符串的长度,而不会考虑字符串中的具体字符。在这里,"abcdef" 的长度为 6,"bbb" 的长度为 3,strlen(str2) - strlen(str1)相减的结果是-3,但是由于strlen的返回值是无符号整型,两个无符号整型相减结果也会被当作无符号整型看待,无符号整型的结果必定大于0,-3的补码:11111111111111111111111111111101,用无符号看待结果大于0,所以输出结果将是 "str1


模拟实现strlen


方式一:计数器方式


size_t my_strlen(const char* str)
{
  int count = 0;
  while (*str != '\0')
  {
    count++;
    str++;
  }
  return count;
}


方式二:递归方法


size_t my_strlen(const char* str)
{
  const char* start = str;
  while (*str != '\0')
  {
    str++;
  }
  return str - start;
}


方式三:指针-指针的方式


size_t my_strlen(const char* str) 
{
  if (*str == '\0')
    return 0;
  else
    return my_strlen(++str) + 1;
}


1.2、strcpy


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


  • Copies the C string pointed by source into the array pointed by destination, including the terminating null character (and stopping at that point).(将由源指针指向的C字符串复制到由目标指针指向的数组中,包括终止空字符(并在那一点停止复制))
  • 源字符串必须以 '\0' 结束。
  • 会将源字符串中的 '\0' 拷贝到目标空间。
  • 目标空间必须足够大,以确保能存放源字符串。
  • 目标空间必须可变。
  • 学会模拟实现。


#include<stdio.h>
#include<string.h>
int main()
{
  //char* strcpy(char* destination, const char* source);
  char arr1[20] = { 0 };
  char arr2[] = "hello!";
  char *arr3 = strcpy(arr1, arr2);//接受返回值
  printf("%s\n", arr1);//不接受返回值打印
  printf("%s\n", arr3);//接受返回值打印
  return 0;
}


运行结果:



注意1:strcpy拷贝会将'\0'拷贝至目的地



注意2:strcpy的源头必须保证有'\0'字符



模拟实现strcpy


char* my_strcpy(char* destination, const char* source)
{
  char* dest = destination;
  assert(source != '\0' && destination != '\0');//头文件<assert.h>
  while (*source)
  {
    *destination = *source;
    destination++;
    source++;
  }
  *destination = *source;//拷贝'\0'
  //return destination;//error,此时destination地址已经被改变
  return dest;
}


优化


char* my_strcpy(char* destination, const char* source)
{
  char* dest = destination;
  assert(source != '\0' && destination != '\0');//头文件<assert.h>
  while (*destination++ = *source++)
  {
    ;//后置++,先使用后++
         //'\0'的ASCII码值为0,while(0)为假退出循环
  }
  //return destination;//error,此时destination地址已经被改变
  return dest;
}


1.3、strcat


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


  • Appends a copy of the source string to the destination string. The terminating null character in destination is overwritten by the first character of source, and a null-character is included at the end of the new string formed by the concatenation of both in destination.(将源字符串的副本追加到目标字符串中。目标字符串中的终止空字符会被源字符串的第一个字符覆盖,并且在目标字符串中形成的新字符串的末尾包含一个空字符,用于表示字符串的结束。)
  • 源字符串必须以 '\0' 结束。
  • 目标空间必须有足够的大,能容纳下源字符串的内容。
  • 目标空间必须可修改。


#include<stdio.h>
#include<string.h>
int main()
{
  char arr1[20] = "i";
  char arr2[] = "love you";
  strcat(arr1, arr2);//追加字符串
  printf("%s\n", arr1);
  return 0;
}


运行结果:



模拟实现strcat:


char* my_strcat(char* destination, const char* source)
{
  char* dest = destination;
    assert(source != '\0' && destination != '\0');//头文件<assert.h>
  while (*destination!='\0')
  {
    destination++;//找到目标空间的\0
  }
  while (*destination++ = *source++)
  {
    ;//把目标空间\0及以后的空间拷贝上源头的字符串
  }
  return dest;
}


那我们字符串自己给自己追加,如何?



解释:很明显,程序崩溃了。因为在追加字符串的时候,首先就要找到目标空间的\0,然后把它修改成源字符串的第一个字母,但是由于是自己给自己追加字符串,导致把源字符串的\0也修改掉了,字符串就会一直拷贝去找\0,但是源字符串的\0已经被修改,导致一直追加字符串,最后空间不足程序崩溃。


1.4、strcmp


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


  • This function starts comparing the first character of each string. If they are equal to each other, it continues with the following pairs until the characters differ or until a terminating null-character is reached.(这个函数从两个字符串的第一个字符开始比较。如果它们相等,它会继续比较后续的字符对,直到找到不同的字符或者遇到终止空字符为止。)
  • 标准规定:


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


那么如何判断两个字符串?

#include<stdio.h>
#include<string.h>
int main()
{
  //比较的是字母的ASCII码值,a - 97,b - 98
  //int strcmp(const char* str1, const char* str2);
  char arr1[] = "hello";
  char arr2[] = "hellc";
  if (strcmp(arr1, arr2) > 0)
  {
    printf("arr1 > arr2");
  }
  else if (strcmp(arr1, arr2) < 0)
  {
    printf("arr1 < arr2");
  }
  else
  {
    printf("arr1 = arr2");
  }
  return 0;
}


运行结果:



模拟实现strcmp:


int my_strcmp(const char* str1, const char* str2)
{
  assert(str1 != '\0' && str2 != '\0');//头文件<assert.h>
    while (*str1 == *str2)//字符串相等
  {
    if (*str1 == '\0')//两个字符串相等
      return 0;
    str1++;
    str2++;
  }
  //两个字符串不相等
  if (*str1 > *str2)
    return 1;
  else
    return -1;
}


优化:


int my_strcmp(const char* str1, const char* str2)
{
  assert(str1 != '\0' && str2 != '\0');//头文件<assert.h>
    while (*str1 == *str2)//字符串相等
  {
    if (*str1 == '\0')//两个字符串相等
      return 0;
    str1++;
    str2++;
  }
  //两个字符串不相等
  return (*str1-*str2);//繁返回他们之间的差值
}


【编织代码之纵横字符与绚丽字符串](中):https://developer.aliyun.com/article/1424777

相关文章
|
4月前
|
算法
算法编程(二十八):重新排列单词间的空格
算法编程(二十八):重新排列单词间的空格
35 0
|
3月前
|
C语言
【编织代码之纵横字符与绚丽字符串](中)
【编织代码之纵横字符与绚丽字符串]
|
3月前
【编织代码之纵横字符与绚丽字符串](下)
【编织代码之纵横字符与绚丽字符串]
|
2月前
|
监控 API 计算机视觉
OpenCV这么简单为啥不学——1.2、图片截取(数组截取)
OpenCV这么简单为啥不学——1.2、图片截取(数组截取)
17 0
|
4月前
|
算法 索引
算法编程(二十):仅仅反转字母
算法编程(二十):仅仅反转字母
28 0
|
4月前
|
存储 算法 API
☆打卡算法☆LeetCode 151. 颠倒字符串中的单词 算法解析
☆打卡算法☆LeetCode 151. 颠倒字符串中的单词 算法解析
|
9月前
|
Java
字符串变形(字符串大小写切换和变现)
字符串变形(字符串大小写切换和变现)
67 0
|
11月前
|
小程序 索引
如何实现文字逐个出现的打字机效果
今天分享一下如何在微信小游戏制作工具中实现文字逐个出现的打字机效果,这个小功能可以用于游戏中的文字对白的展示,如果你要做的是一个文字类游戏的话,那么肯定用的上。
94 0
|
自然语言处理 算法
☆打卡算法☆LeetCode 68、文本左右对齐 算法解析
“给定单词数组和一个长度maxWidth,重新排版单词,使其成为恰好有maxWWidth个字符,且左右对齐的文本。”
☆打卡算法☆LeetCode 97、交错字符串 算法解析
“给定三个字符串s1、s2、s3,验证s3是否是s1和s2的交错组成的。”

热门文章

最新文章